无法在 'DOMWindow' 上执行 'postMessage':target/origin 不匹配 http 与 https
Failed to execute 'postMessage' on 'DOMWindow': target/origin mismatch http vs https
我很抱歉我的问题让我很困惑。我真的很为难,因为这导致我的生产站点出现问题。
我的网站上有一个 javascript 播放器,它播放可以托管在 youtube、soundcloud 或 vimeo 上的歌曲列表。昨天我注意到这个错误,通常在您尝试使用播放器按钮通过 "skipping" 加载新歌曲时出现。这个错误是最近一两天才开始的。我在 youtube api 发行说明中没有看到任何新内容,并且此错误发生在使用 Chrome、Firefox 和 Safari 时,因此它很可能与浏览器的更改无关。不过,我正在使用的东西发生了变化,因为我已经 18 天没有推送新代码了。
示例播放列表如下:http://www.muusical.com/playlists/programming-music
我想我已经隔离了重现错误的方法,步骤如下:
- 播放 YouTube 托管的歌曲。
- 跳到列表中的任何其他歌曲(无论是按跳过按钮还是直接按歌曲行项目上的播放按钮)。
*请注意,如果播放列表中的第一首歌曲是 youtube 歌曲,即使不播放最初加载的 youtube 歌曲而直接跳到另一首歌曲也会产生错误。
基本上,错误似乎是在您加载 and/or 播放了一首 YouTube 歌曲并试图跳到另一首歌曲时发生的。
如果您发现此行为有异常,请告诉我。
我在控制台中看到这个错误:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.muusical.com') does not match the recipient window's origin ('http://www.muusical.com').
我使用 youtube 加载播放器 javascript api:
new YT.Player('playlist-player', {
playerVars: { 'autoplay': 1, 'fs': 0 },
videoId: "gJ6APKIjFQY",
events: {
'onReady': @initPlayerControls,
'onStateChange': @onPlayerStateChange
}
})
生成此 iframe 的对象:
<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src="https://www.youtube.com/embed/gJ6APKIjFQY?autoplay=1&enablejsapi=1&origin=http%3A%2F%2Fwww.muusical.com"></iframe>
从上面的 youtube 歌曲中点击跳过后,这是我在 iframe 中看到的加载内容:
<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src=""></iframe>
我支持 youtube、soundcloud 和 vimeo 歌曲。似乎一旦加载了 YouTube 歌曲,"origin" 就会从 http 更改为 https。我认为没有必要包括其他主机的嵌入方法,因为即使整个播放列表只是 youtube 也会发生此错误,并且它不会出现在仅包含来自 soundcloud 和 vimeo 的歌曲的播放列表中。
此外,这就是我加载 youtube 的方式 javascript:
// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
如果您需要我澄清任何事情,请告诉我,在此先感谢您的查看。
我读过一些关于这个的文章,一些 SO 帖子在这里和那里还有这个 link:https://code.google.com/p/gdata-issues/issues/detail?id=5788
我正要对你的问题添加评论,说我对此感到疯狂......但是当我开始描述我的设置时,我找到了避免这个问题的方法^^。
我从一个空的 div
元素开始,然后使用 Youtube Iframe API 将其变成具有所有必要选项的 iframe
。
我有多个像这个这样的 div,并且通常使用相同的 JS 变量来存储所有这些播放器,但一次一个(一个替换另一个,依此类推...... - 它可能会更好,我知道)。
为了解决这个问题,我想用 摧毁 玩家 youtubePlayer.destroy();
然后再从另一个元素构建新的玩家。我的 Chrome 控制台中不再出现 JS 错误:).
希望对你有帮助,我能读到的关于 http 和 https 的所有文献都不适用于我的情况,因为我没有自己设置 iframe URL,而我的网站恰好是 不 https ...
我确实在 HTML 中恢复了异步调用而不是静态 script
标记,但我认为这没有必要。
EDIT:这个错误消息实际上非常具有误导性,它只是含糊地表示:你没有以正确的方式使用 youtube API:)
@sodawillow 的回答部分正确,但我想提供解决方案的详细信息以及导致我的代码停止调用 .destroy()
方法以删除 youtube 播放器的原因。
我的网站有一个播放器,可以交换来自不同网站的歌曲,其中之一是 Youtube。根据播放器的类型,可以使用不同的方法来移除播放器。我的代码检查是否存在 youtube 播放器,如果通过检查,则它使用只有 youtube 播放器才有的 .destroy()
方法。问题是 YouTube 更改了播放器对象上某些静态变量的名称。例如,如果我通过以下方式创建了一个播放器:
var player = new YT.Player('playlist-player', {
playerVars: { 'autoplay': 1, 'fs': 0 },
videoId: "gJ6APKIjFQY",
events: {
}
})
然后会有一个变量 player.L
保存字符串 "player"
。因此,为了检查当前播放器是否是 YouTube 播放器并将其删除,我这样做了:
if (player.L == "player") {
player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}
最近 Youtube 将字符串 "player"
的位置更改为现在位于 player.M
。我可以更改上面的代码以检查 player.M
而不是 player.L
,这会起作用,但为了避免将来出现此问题,我改为实施:
if (player.destroy) {
player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}
只要 Youtube 不删除 .destroy()
方法,这不会导致任何问题。
所以综上所述,问题正如@sodawillow 猜测的那样,我没有使用 .destroy()
方法删除 Youtube 播放器。原因是 Youtube 对其 api 进行了一些未经宣布的更改,更改了一些静态变量的位置。
我的解决方案是将所有 Youtube 播放器逻辑写在单独的页面中(尽可能空白),并在 IFRAME
标记中引用该页面。
<iframe src="/youtube_frame/?data=SOME_DATA -%>" height="400px" width="100%" frameborder="0" border="0" scrolling="no"></iframe>
那么,你的youtube_frame.html
会是这样的:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
// event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
console.log("OnplayerStateChange");
if (event.data == YT.PlayerState.PLAYING && !done) {
console.log("OnplayerStateChange - If statement");
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
(作为旁注:我的上下文是 Prototype.js 干扰了事件 'OnStateChange',我们无法消除这种依赖性。
使用 jsfiddle 对重现问题没有用,因为它几乎没有依赖项。
我的应用程序内置于 Rails,并使用此插件显示视频播放列表:https://github.com/Giorgio003/Youtube-TV/)
此错误属于 Google Youtube API。
在“https://www.youtube.com/iframe_api”内:
if (!window['YT']) {
var YT = {loading: 0, loaded: 0};
}
if (!window['YTConfig']) {
var YTConfig = {'host': 'http://www.youtube.com'};
}
他们使用 http 而不是 https。
我们需要覆盖 'host' 选项和 'widget_referrer' 与 'origin' 相同。
player = new YT.Player('player', {
host: 'https://www.youtube.com',
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE'
...
origin: "https://www.enziin.com",
widget_referrer: "https://www.enziin.com"
}
祝你好运。
我很抱歉我的问题让我很困惑。我真的很为难,因为这导致我的生产站点出现问题。
我的网站上有一个 javascript 播放器,它播放可以托管在 youtube、soundcloud 或 vimeo 上的歌曲列表。昨天我注意到这个错误,通常在您尝试使用播放器按钮通过 "skipping" 加载新歌曲时出现。这个错误是最近一两天才开始的。我在 youtube api 发行说明中没有看到任何新内容,并且此错误发生在使用 Chrome、Firefox 和 Safari 时,因此它很可能与浏览器的更改无关。不过,我正在使用的东西发生了变化,因为我已经 18 天没有推送新代码了。
示例播放列表如下:http://www.muusical.com/playlists/programming-music
我想我已经隔离了重现错误的方法,步骤如下:
- 播放 YouTube 托管的歌曲。
- 跳到列表中的任何其他歌曲(无论是按跳过按钮还是直接按歌曲行项目上的播放按钮)。
*请注意,如果播放列表中的第一首歌曲是 youtube 歌曲,即使不播放最初加载的 youtube 歌曲而直接跳到另一首歌曲也会产生错误。
基本上,错误似乎是在您加载 and/or 播放了一首 YouTube 歌曲并试图跳到另一首歌曲时发生的。
如果您发现此行为有异常,请告诉我。
我在控制台中看到这个错误:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.muusical.com') does not match the recipient window's origin ('http://www.muusical.com').
我使用 youtube 加载播放器 javascript api:
new YT.Player('playlist-player', {
playerVars: { 'autoplay': 1, 'fs': 0 },
videoId: "gJ6APKIjFQY",
events: {
'onReady': @initPlayerControls,
'onStateChange': @onPlayerStateChange
}
})
生成此 iframe 的对象:
<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src="https://www.youtube.com/embed/gJ6APKIjFQY?autoplay=1&enablejsapi=1&origin=http%3A%2F%2Fwww.muusical.com"></iframe>
从上面的 youtube 歌曲中点击跳过后,这是我在 iframe 中看到的加载内容:
<iframe id="playlist-player" frameborder="0" allowfullscreen="1" title="YouTube video player" width="640" height="360" src=""></iframe>
我支持 youtube、soundcloud 和 vimeo 歌曲。似乎一旦加载了 YouTube 歌曲,"origin" 就会从 http 更改为 https。我认为没有必要包括其他主机的嵌入方法,因为即使整个播放列表只是 youtube 也会发生此错误,并且它不会出现在仅包含来自 soundcloud 和 vimeo 的歌曲的播放列表中。
此外,这就是我加载 youtube 的方式 javascript:
// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
如果您需要我澄清任何事情,请告诉我,在此先感谢您的查看。
我读过一些关于这个的文章,一些 SO 帖子在这里和那里还有这个 link:https://code.google.com/p/gdata-issues/issues/detail?id=5788
我正要对你的问题添加评论,说我对此感到疯狂......但是当我开始描述我的设置时,我找到了避免这个问题的方法^^。
我从一个空的 div
元素开始,然后使用 Youtube Iframe API 将其变成具有所有必要选项的 iframe
。
我有多个像这个这样的 div,并且通常使用相同的 JS 变量来存储所有这些播放器,但一次一个(一个替换另一个,依此类推...... - 它可能会更好,我知道)。
为了解决这个问题,我想用 摧毁 玩家 youtubePlayer.destroy();
然后再从另一个元素构建新的玩家。我的 Chrome 控制台中不再出现 JS 错误:).
希望对你有帮助,我能读到的关于 http 和 https 的所有文献都不适用于我的情况,因为我没有自己设置 iframe URL,而我的网站恰好是 不 https ...
我确实在 HTML 中恢复了异步调用而不是静态 script
标记,但我认为这没有必要。
EDIT:这个错误消息实际上非常具有误导性,它只是含糊地表示:你没有以正确的方式使用 youtube API:)
@sodawillow 的回答部分正确,但我想提供解决方案的详细信息以及导致我的代码停止调用 .destroy()
方法以删除 youtube 播放器的原因。
我的网站有一个播放器,可以交换来自不同网站的歌曲,其中之一是 Youtube。根据播放器的类型,可以使用不同的方法来移除播放器。我的代码检查是否存在 youtube 播放器,如果通过检查,则它使用只有 youtube 播放器才有的 .destroy()
方法。问题是 YouTube 更改了播放器对象上某些静态变量的名称。例如,如果我通过以下方式创建了一个播放器:
var player = new YT.Player('playlist-player', {
playerVars: { 'autoplay': 1, 'fs': 0 },
videoId: "gJ6APKIjFQY",
events: {
}
})
然后会有一个变量 player.L
保存字符串 "player"
。因此,为了检查当前播放器是否是 YouTube 播放器并将其删除,我这样做了:
if (player.L == "player") {
player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}
最近 Youtube 将字符串 "player"
的位置更改为现在位于 player.M
。我可以更改上面的代码以检查 player.M
而不是 player.L
,这会起作用,但为了避免将来出现此问题,我改为实施:
if (player.destroy) {
player.destroy();
} else {
//handle the removal of the Soundcloud or Vimeo player.
}
只要 Youtube 不删除 .destroy()
方法,这不会导致任何问题。
所以综上所述,问题正如@sodawillow 猜测的那样,我没有使用 .destroy()
方法删除 Youtube 播放器。原因是 Youtube 对其 api 进行了一些未经宣布的更改,更改了一些静态变量的位置。
我的解决方案是将所有 Youtube 播放器逻辑写在单独的页面中(尽可能空白),并在 IFRAME
标记中引用该页面。
<iframe src="/youtube_frame/?data=SOME_DATA -%>" height="400px" width="100%" frameborder="0" border="0" scrolling="no"></iframe>
那么,你的youtube_frame.html
会是这样的:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
// event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
console.log("OnplayerStateChange");
if (event.data == YT.PlayerState.PLAYING && !done) {
console.log("OnplayerStateChange - If statement");
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
(作为旁注:我的上下文是 Prototype.js 干扰了事件 'OnStateChange',我们无法消除这种依赖性。 使用 jsfiddle 对重现问题没有用,因为它几乎没有依赖项。 我的应用程序内置于 Rails,并使用此插件显示视频播放列表:https://github.com/Giorgio003/Youtube-TV/)
此错误属于 Google Youtube API。
在“https://www.youtube.com/iframe_api”内:
if (!window['YT']) {
var YT = {loading: 0, loaded: 0};
}
if (!window['YTConfig']) {
var YTConfig = {'host': 'http://www.youtube.com'};
}
他们使用 http 而不是 https。
我们需要覆盖 'host' 选项和 'widget_referrer' 与 'origin' 相同。
player = new YT.Player('player', {
host: 'https://www.youtube.com',
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE'
...
origin: "https://www.enziin.com",
widget_referrer: "https://www.enziin.com"
}
祝你好运。