【问题标题】:Failed to execute 'postMessage' on 'DOMWindow': https://www.youtube.com !== http://localhost:9000无法在“DOMWindow”上执行“postMessage”:https://www.youtube.com !== http://localhost:9000
【发布时间】:2015-02-18 19:13:15
【问题描述】:

这是我收到的错误消息:

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided
('https://www.youtube.com') does not match the recipient window's origin 
('http://localhost:9000').

我见过其他类似的问题,目标来源是http://www.youtube.com,收件人来源是https://www.youtube.com,但没有一个像我这样的问题,目标是https://www.youtube.com,来源是http://localhost:9000

  1. 我不明白这个问题。有什么问题?
  2. 我该如何解决?

【问题讨论】:

标签: javascript angularjs youtube youtube-api youtube-iframe-api


【解决方案1】:

我认为我们可以自定义 YT.Player 的 sendMessage

playerOptions.playerVars.origin = window.location.origin or your domain.
this.youtubePlayer = new YT.Player(element,playerOptions);
this.youtubePlayer.sendMessage = function (a) {
   a.id = this.id, a.channel = "widget", a = JSON.stringify(a);
   var url = new URL(this.h.src), origin = url.searchParams.get("origin");
   if (origin && this.h.contentWindow) {
       this.h.contentWindow.postMessage(a, origin)
   }
}

我在我的项目中使用了这个函数来解决。

【讨论】:

    【解决方案2】:

    这对我有帮助(使用 Vue.js)

    在这里找到vue-youtube

    mounted() {
      window.YTConfig = {
        host: 'https://www.youtube.com/iframe_api'
      }
      const host = this.nocookie ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com'
    
      this.player = player(this.$el, {
        host,
        width: this.width,
        height: this.height,
        videoId: this.videoId,
        playerVars: this.playerVars
      })
      ...
    }
    

    更新: 像这样的魅力工作:

    ...
    youtube(
      video-id="your_video_code_here"
      nocookie
    )
    ...
    data() {
      return {
        playerVars: {
          origin: window.location.href,
        },
      };
    },
    

    【讨论】:

    • 你能说得更具体点吗?这段代码的哪一部分有帮助? (我也在使用 Vue 时遇到这个问题)
    【解决方案3】:

    它看起来只是一个 Chrome 安全系统来阻止重复请求,使用 CORB。

    https://www.chromestatus.com/feature/5629709824032768

    在我的情况下,YouTube 在第一次加载具有许多视频 API 数据请求、高负载的同一网页后阻止访问。

    对于负载较低的页面,不会出现此问题。

    在 Safari 和其他非 Chronuim 浏览器中,不会出现此问题。

    如果我在新浏览器中加载网页,则不会出现此问题,当我重新加载同一页面时,会出现此问题。

    【讨论】:

    • 感谢您对 chrome 等人的见解。顺便说一句,我注意到当我向下滚动页面时,没有显示嵌入的视频,错误计数会永久停止(直到重新加载页面)。否则,在新页面加载时,错误计数器会不断产生错误,直到浏览器变得无响应(产生这个的 wordpress 插件把我带到了这里)。
    【解决方案4】:

    只需在播放器的paramVars 属性中添加参数"origin" 和您网站的URL,如下所示:

    this.player = new window['YT'].Player('player', {
        videoId: this.mediaid,
        width: '100%',
        playerVars: { 
            'autoplay': 1,
            'controls': 0,
            'autohide': 1,
            'wmode': 'opaque',
            'origin': 'http://localhost:8100' 
        },
    }
    

    【讨论】:

    • origin:window.location,在属性中涵盖开发和生产
    • @JamesBailey window.location.origin .. window.location 是一个对象。
    • 正如 API 文档所说,origin playerVar 仅用于纯 iframe 实现。不是 JS API 之一。
    • 所有这些“修复”在 2020 年对我们来说都不起作用。还要补充一点,当错误显示时,它的每页随机加载。这是我们网站和 youtube 之间的竞争条件。
    • window.location.host
    【解决方案5】:

    添加origin=${window.location.host} or "*" 是不够的。

    在它之前添加https://,它将起作用。

    另外,请确保您使用的是可嵌入的 URL:取出视频 ID 并将具有 YouTube 视频前缀和视频 ID + 嵌入定义的字符串连接起来。

    【讨论】:

      【解决方案6】:

      就我而言,这与延迟加载 iframe 有关。删除 iframe HTML 属性 loading="lazy" 为我解决了这个问题。

      【讨论】:

        【解决方案7】:

        只是希望避免控制台错误,我使用与 Artur 早期答案类似的方法解决了这个问题,步骤如下:

        1. 已将 YouTube Iframe API(来自 https://www.youtube.com/iframe_api)下载到本地 yt-api.js 文件。
        2. 删除了插入 www-widgetapi.js 脚本的代码。
        3. 已将 www-widgetapi.js 脚本(来自 https://s.ytimg.com/yts/jsbin/www-widgetapi-vfl7VfO1r/www-widgetapi.js)下载到本地 www-widgetapi.js 文件。
        4. 将导致控制台错误的 postMessage 调用中的 targetOrigin 参数替换为“*”(表示没有偏好 - 请参阅 https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)。
        5. 将修改后的 www-widgetapi.js 脚本附加到 yt-api.js 脚本的末尾。

        这不是最好的解决方案(修补本地脚本来维护,失去对消息发送位置的控制)但它解决了我的问题。

        在使用此解决方案之前,请参阅此处关于删除 targetOrigin URI 的安全警告 - https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

        Patched yt-api.js example

        【讨论】:

          【解决方案8】:

          在某些情况下(正如一位评论者提到的),如果您在 DOM 中移动播放器,可能会导致这种情况,例如 append 等。

          【讨论】:

            【解决方案9】:

            至少在我的例子中,这似乎是一种无害的“未准备好”情况,API 会重试直到成功。

            我得到了其中的 2 到 9 个(在我的最坏情况测试仪上,2009 年的 FossilBook,通过蜂窝热点打开了 20 个标签)....但是视频正常运行。一旦它运行我对 seekTo 的基于 postMessage 的调用肯定可以工作,还没有测试过其他人。

            【讨论】:

            • 确实会出现我在浪费时间担心这个错误,而事实上网站和嵌入的视频都工作正常......网站的用户不会担心关于这个,也许我也不会。
            【解决方案10】:

            如果您在对window.postMessage() 的调用中未指定targetOrigin,也会收到此消息。

            在本例中,我们将消息发布到第一个 iFrame 并使用 * 作为目标,这应该允许与任何 targetOrigin 进行通信。

            window.frames[0].postMessage({
                                message : "Hi there",
                                command :"hi-there-command",
                                data : "Some Data"
                            }, '*')
            

            【讨论】:

              【解决方案11】:

              我也遇到了同样的问题,然后我访问了official Youtube Iframe Api,在那里我找到了这个:

              用户的浏览器必须支持 HTML5 postMessage 功能。大多数现代浏览器都支持 postMessage

              然后逛了一下官方页面也遇到了这个问题。只需访问 official Youtube Iframe Api 并查看控制台日志。我的 Chrome 版本是 79.0.3945.88。

              【讨论】:

                【解决方案12】:

                你可以试试:

                document.getElementById('your_id_iframe').contentWindow.postMessage('your_message', 'your_domain_iframe')
                

                【讨论】:

                  【解决方案13】:

                  我的是:

                  <youtube-player
                    [videoId]="'paxSz8UblDs'"
                    [playerVars]="playerVars"
                    [width]="291"
                    [height]="194">
                  </youtube-player>
                  

                  我刚刚删除了带有 playerVars 的行,它在控制台上正常工作。

                  【讨论】:

                    【解决方案14】:

                    您可以将 JavaScript 保存到本地文件中:

                    进入第一个文件,player_api把这段代码:

                    if(!window.YT)var YT={loading:0,loaded:0};if(!window.YTConfig)var YTConfig={host:"https://www.youtube.com"};YT.loading||(YT.loading=1,function(){var o=[];YT.ready=function(n){YT.loaded?n():o.push(n)},window.onYTReady=function(){YT.loaded=1;for(var n=0;n<o.length;n++)try{o[n]()}catch(i){}},YT.setConfig=function(o){for(var n in o)o.hasOwnProperty(n)&&(YTConfig[n]=o[n])}}());
                    

                    进入第二个文件,找到代码:this.a.contentWindow.postMessage(a,b[c]);

                    并将其替换为:

                    if(this._skiped){
                        this.a.contentWindow.postMessage(a,b[c]); 
                    }
                    this._skiped = true;
                    

                    当然,您可以连接成一个文件 - 效率会更高。 这不是一个完美的解决方案,但它的工作原理!

                    我的来源:yt_api-concat

                    【讨论】:

                    • 为我修复了它。无论如何,这些文件都在本地,所以适合我的用例。
                    • 这对我也有用,但我不知道为什么。你能解释一下为什么会解决这个问题吗?
                    • 谢谢,在第二次 ajax 调用中回答了我的问题:stackoverflow.com/questions/58232081/…
                    • 在我看来,使用本地文件作为库,尤其是第三方服务库,是一种非常糟糕的编码方式。没有?
                    • @DamienC 这肯定不太理想。但是,基于此线程上的所有其他“修复”,我并不感到惊讶(我也不会真正判断)其他开发人员手动更改 API 代码。
                    【解决方案15】:

                    我认为这是目标来源为https 的问题。我怀疑这是因为您的 iFrame url 使用的是 http 而不是 https。尝试将您尝试嵌入的文件的 url 更改为 https

                    例如:

                    '//www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
                    

                    成为:

                    'https://www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
                    

                    【讨论】:

                    • 这似乎奏效了。谢谢!所以问题是httphttps?域不同(youtube 与 localhost)无关紧要?目标来源与收件人来源到底是什么?你所说的如何改变收件人来源(我的网址仍然是 localhost:9000)?
                    • 这个错误有点误导。它实际上与您在localhost:9000 上无关。问题实际上在于您使用 youtube-api 的方式。当您在代码中将 api 声明为 tag.src = "https://www.youtube.com/iframe_api"; 时,您就是在告诉 youtube 您要使用 ssl。因此,我建议的更改将您更改为使用 ssl 来请求视频。错误只是说您正在混合使用 ssl 和非 ssl 调用。
                    • 当我尝试在 dom 中移动 iframe 时遇到了这个问题。 playerEl = document.querySelector('iframe#ytplayer'); anotherEl.appendChild(playerEl); // yt complains on subsequent api calls
                    • 如果我使用 javascript 加载 YouTube 播放器会怎样?
                    • 对于 youtube 已更改为 https://,而我的域是 https:// 仍然无法解决我的问题。在“DOMWindow”上执行“postMessage”失败:提供的目标源(“youtube.com”)与接收窗口的源(“test.dev”)不匹配。
                    【解决方案16】:

                    可能有以下任何一种,但它们都会导致 DOM 在被 javascript 访问之前没有加载。

                    因此,在实际调用 JS 代码之前,您必须确保: * 确保容器在调用任何 javascript 之前已加载 * 确保目标 URL 被加载到它必须的任何容器中

                    当我试图让我的 Javascript 在导致错误消息的主页的 onLoad 之前运行良好时,我遇到了类似的问题,但在我的本地。我通过简单地等待整个页面加载然后调用所需的函数来修复它。

                    您可以简单地通过在页面加载时添加超时功能并调用您的 onload 事件来做到这一点:

                    window.onload = 新函数() { 设置超时(函数(){ // 一些加载事件 }, 10); }

                    这将确保您尝试的内容在 onLoad 被触发后执行良好。

                    【讨论】:

                    • 不幸的是,将所有内容放入 document.addEventListener("DOMContentLoaded", function () { 并没有帮助。
                    【解决方案17】:

                    确保您从以下 URL 加载:

                    https://www.youtube.com/embed/HIbAz29L-FA?modestbranding=1&playsinline=0&showinfo=0&enablejsapi=1&origin=https%3A%2F%2Fintercoin.org&widgetid=1

                    注意“origin”组件以及“enablejsapi=1”。来源必须与您的域相匹配,然后它将被列入白名单并正常工作。

                    【讨论】:

                      【解决方案18】:

                      您可以将您的 iframe 更改为这样,并将来源添加为您当前的网站。它解决了我的浏览器上的错误。

                      <iframe class="test-testimonials-youtube-group"  type="text/html" width="100%" height="100%"
                        src="http://www.youtube.com/embed/HiIsKeXN7qg?enablejsapi=1&origin=http://localhost:8000"
                        frameborder="0">
                      </div>
                      

                      参考:https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

                      【讨论】:

                        【解决方案19】:

                        删除 DNS 预取将解决此问题。

                        如果您使用的是 WordPress,请在主题的 functions.php 中添加这一行

                        remove_action( 'wp_head', 'wp_resource_hints', 2 );
                        

                        【讨论】:

                          【解决方案20】:

                          我遇到了同样的错误。我的错误是enablejsapi=1 参数在iframe src 中不存在。

                          【讨论】:

                            【解决方案21】:

                            设置这个似乎可以解决它:

                              this$1.player = new YouTube.Player(this$1.elementId, {
                                videoId: videoId,
                                host: 'https://www.youtube.com',
                            

                            【讨论】:

                            • 使它成为http(而不是https)解决了我的问题。
                            • 这也为我修复了它。也可以这样做:host: `${window.location.protocol}//www.youtube.com`,
                            • 所有这些“修复”在 2020 年对我们来说都不起作用。另外,当错误显示时,每页随机加载。这是我们网站和 youtube 之间的竞争条件。
                            • 添加主机和原点对我有用
                            【解决方案22】:

                            这个确切的错误与“在某些网站或应用程序上播放”时 Youtube 的内容块有关。更具体地说,由 WMG(华纳音乐集团)提供。

                            但是,错误消息确实表明将 https iframe 导入到 http 站点是问题所在,但在这种情况下并非如此。

                            【讨论】:

                              【解决方案23】:

                              我遇到了同样的问题,事实证明这是因为我运行了 Chrome 扩展程序“HTTPS Everywhere”。禁用扩展解决了我的问题。

                              【讨论】:

                                【解决方案24】:

                                尝试使用window.location.href 来匹配窗口的来源。

                                【讨论】:

                                • 很好,我尝试了所有其他答案,这对我有用!
                                【解决方案25】:

                                我认为错误的描述具有误导性,最初与播放器对象的错误使用有关。

                                在滑块中切换到新视频时,我遇到了同样的问题。

                                当简单地使用player.destroy() 函数described here 时,问题就消失了。

                                【讨论】:

                                猜你喜欢
                                • 2018-05-29
                                • 2019-11-05
                                • 2018-05-30
                                • 2018-11-24
                                • 2019-12-09
                                • 2016-12-11
                                • 1970-01-01
                                • 2016-08-20
                                相关资源
                                最近更新 更多