reactjs - 如何清理单页应用程序上的嵌入式 youtube 订阅按钮

标签 reactjs react-router youtube-api youtube-data-api google-api-js-client

我在我正在构建的单页应用程序中嵌入了一个 youtube 订阅按钮。它加载正常,但是当我导航到不同的路线时,我在该路线的渲染中收到以下错误消息:

cb=gapi.loaded_0:150 
Uncaught DOMException: Blocked a frame with origin "https://www.youtube.com" from accessing a cross-origin frame.
    at Object.nz [as kq] (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:150:257)
    at jz.send (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:148:261)
    at Fz (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:152:349)
    at https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:152:259

即使我去的路线没有订阅按钮(只要我之前在有按钮的路线上),也会发生这种情况。我主要担心的不是错误的原因,而是页面上不再存在的订阅按钮导致了错误。更糟糕的是,当我在整个应用程序中导航时,在我访问的每条具有订阅按钮的路线之后,似乎都会注册一个额外的监听器(或导致此问题的任何原因)。然后在每个路由渲染上多次打印该消息,一次用于自上次刷新以来已安装的每个按钮。作为引用,我附上了我的组件:

import React, { useEffect, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import useScript from 'react-script-hook';
import './YoutubeSubscriberButton.scss';

interface Props {
    youtubeChannel: string
}

type gapiType = typeof gapi;
interface gapiYt extends gapiType {
    ytsubscribe: {
        render: (container: HTMLElement, parameters: {'channel': string, 'layout': string}) => any
    }
}

const YoutubeSubscriberButton: React.FC<Props> = observer(({ youtubeChannel }: Props): JSX.Element|null => {
    const [gapiLoading, gapiError] = useScript({ src: 'https://apis.google.com/js/platform.js'});
    const containerRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const container = containerRef.current;
        if (!youtubeChannel || !container) {
            return;
        }

        while (container.firstChild) {
            container.removeChild(container.firstChild);
        }

        if (gapiLoading || gapiError) {
            return;
        }

        (gapi as gapiYt).ytsubscribe.render(container, {
            'channel': youtubeChannel,
            'layout': 'full'
        });

        return (() =>{
            while (container && container.firstChild) {
                container.removeChild(container.firstChild);
            }
        });
    }, [youtubeChannel, gapiLoading, gapiError]);

    return (
        <div className="youtube-subscriber-button-component">
            <div className="youtube-subscriber-button-container" ref={containerRef}/>
        </div>
    );
});

export default YoutubeSubscriberButton;

有什么好的方法可以让我清理 gapi 对象、youtube 订阅按钮 iframe 或任何导致此问题的原因吗?

最佳答案

我做了 this基于this的CodeSandbox来自 Alex McMillan 的解决方案实现 Youtube 订阅按钮。我使用 React-routes 检查了它,没有发现任何问题。

您可以在 App 函数中替换 data-channelid 以查看它是否正常工作。

您可以找到您唯一的 Youtube channel ID here :

class="g-ytsubscribe"
data-channelid="<YOUR CHANNEL ID HERE>"
data-layout="full"
data-theme="dark"
data-count="hidden"

关于reactjs - 如何清理单页应用程序上的嵌入式 youtube 订阅按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60106932/

相关文章:

javascript - .map() 将错误的值映射到我的 header 标签

javascript - React-router-dom v6 仅渲染默认路由

youtube - 列出大量的YouTube channel 订阅

c# - 带有 OAuth2 的 Youtube API v3 返回 "Received verification code. Closing..."

reactjs - 接下来如何在React应用程序中使用material-ui的rtl布局

javascript - 无法在 CRA 2.0 中使用 CSS 模块

javascript - 如何使用 map 坐标更新 URL?

css - 如何将现有组件添加到 react-native-router-flux

javascript - 使用传播属性 react 渲染组件列表

youtube - 获取 Youtube channel 的视频列表作为 RSS 源