无法在“ DOMWindow”上执行“ postMessage”:https://www.youtube.com!== http:// localhost:9000


165

这是我收到的错误消息:

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. 我该如何解决?


4
我遇到了同样的问题,@ ChrisFranklin进行的以下修复为我修复了该问题;但是很奇怪的是,对于我的问题,我只会在大约一半的时间内收到错误消息,即使这样,视频仍会加载(尽管其他情况会中断)。
dgo

1
@dgo同样的问题,页面加载是随机的。原来(我认为)是由于实际的iframe内容在其他尝试执行postMessage时还没有完全准备好。因此,这是一个竞赛条件。而且,如果postMessage在以后发生(用户操作),则可以正常工作而不会出错。
IncredibleHat

甚至Google本身也存在该错误 -打开控制台并在此处播放视频:developers.google.com/youtube/iframe_api_reference
T.Todua

Answers:


92

我认为这与目标来源有关https。我怀疑是因为您使用的是iFrame网址,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';

2
这似乎奏效了。谢谢!所以,问题是httphttps?域名不同(YouTube与本地主机)无关紧要吗?目标原点与接收者原点到底是什么?您说的如何更改收件人的来源(我的URL仍然是localhost:9000)?
亚当·泽纳

30
该错误有点误导。实际上,这与您在场无关localhost:9000。问题实际上出在您使用youtube-api的方式上。当您tag.src = "https://www.youtube.com/iframe_api";在代码中声明api时,就是在告诉youtube您要使用ssl。因此,我建议您将更改更改为使用ssl请求视频。错误只是说您混用了ssl和non-ssl调用。
克里斯·富兰克林

9
当我尝试在dom中移动iframe时遇到了这个问题。 playerEl = document.querySelector('iframe#ytplayer'); anotherEl.appendChild(playerEl); // yt complains on subsequent api calls
posit Labs 2015年

1
如果我使用JavaScript加载YouTube播放器怎么办?
N3R4ZZuRR0

5
对于youtube更改为https://,而我的域为https://仍无法解决我的问题。无法在“ DOMWindow”上执行“ postMessage”:提供的目标原点(“ youtube.com ”)与收件人窗口的原点(“ test.dev ”)不匹配。
vee'Apr

23

只需在播放器"origin"paramVars属性中将参数与您网站的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' },
}

7
来源:window.location,位于涵盖开发和生产的属性中
James Bailey,

3
@JamesBailey window.location.origin.. window.location是一个对象。
Acidic9

正如API文档所说的那样,原始playerVar仅与纯iframe实现一起使用。不是JS API之一。
Damien C

1
所有这些“修复”都不会在2020年对我们起作用。此外,当错误显示时,它的每页加载随机数。这是我们网站和YouTube之间的竞争条件。
IncredibleHat

window.location.host
LeeGee

19

设置它似乎可以解决此问题:

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

3
使其http (而不是https)解决了我的问题。
T.Todua

5
这也为我解决了。也可以做到:host: `${window.location.protocol}//www.youtube.com`
乔尔·沃舍姆

2
所有这些“修复”都不会在2020年对我们起作用。此外,当错误显示时,它的每页加载随机数。这是我们网站和YouTube之间的竞争条件。
IncredibleHat

8

您可以将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


为我修复。无论如何都将文件放在本地,所以适合我的用例。
频繁

这也对我有用,但是我不确定为什么。您能解释一下为什么解决此问题吗?
jchavannes

1
谢谢你,回答我的问题在第二AJAX调用:stackoverflow.com/questions/58232081/...
迪奥戈阿尔梅达

以我的观点,将本地文件用于库,尤其是第三方服务库,是一种非常糟糕的编码方式。不是吗
Damien C

@DamienC肯定不够理想。但是,基于此线程上的所有其他“修复”,其他开发人员手动更改API代码并不感到惊讶(我也不是真的判断)。
Erutan409



3

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


0

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

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

仅使用此处描述player.destroy()功能时,问题就消失了。


请问您是否了解我在YouTube上所经历的事情,以及是否与之相关?stackoverflow.com/q/57649870/470749也许您会得到答案。谢谢!
瑞安

0

我遇到了同样的问题,原来是因为我正在运行Chrome扩展“ HTTPS Everywhere”。禁用扩展解决了我的问题。


0

当“在某些站点或应用程序上播放”时,此确切的错误与Youtube的内容阻止有关。更具体地说,是WMG(华纳音乐集团)。

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


0

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

如果您使用的是WordPress,请将此行添加到主题的functions.php中

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


0

可能存在以下任何一种情况,但是所有这些都导致DOM在被javascript访问之前未加载。

因此,在实际调用JS代码之前,您需要确保以下几点:*确保在调用任何javascript之前已加载容器*请确保将目标URL加载到必须包含的任何容器中

我遇到了类似的问题,但是当我试图在首页的onLoad之前导致我的Javascript运行良好时,这会导致错误消息。我已经解决了,只需等待整个页面加载,然后调用所需的函数即可。

您可以简单地通过在页面加载后添加超时函数来执行此操作,然后调用onload事件,例如:

window.onload = new function(){setTimeout(function(){//一些onload事件},10); }

这样可以确保触发onLoad后,您尝试执行的操作能够很好地执行。


document.addEventListener("DOMContentLoaded", function () {不幸的是,将所有内容放进去都无济于事。
瑞安

0

当未在调用中指定targetOrigin时,也会收到此消息window.postMessage()

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

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

0

在我看来,至少这似乎是一种无害的“未就绪”条件,API会重试直到成功。

我得到了其中的两个到九个(在最坏的情况下是测试用的2009 FossilBook,其中有20个通过蜂窝热点打开的标签)....但随后视频正常运行。一旦运行了我基于postMessage的对seekTo的调用就可以正常工作,就没有测试其他对象。


0

在某些情况下(如一位评论者所述),这可能是由于您在DOM之类的DOM中移动播放器而引起的,例如append等等。


-1

你可以试试 :

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.