Не удалось выполнить "postMessage" в "DOMWindow": https://www.youtube.com!== http://localhost:9000
Это сообщение об ошибке, которое я получаю:
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
,
- Я не понимаю проблемы. В чем проблема?
- Как я могу это исправить?
29 ответов
Я считаю, что это проблема с целевым происхождением https
, Я подозреваю, что это потому, что ваш URL-адрес iFrame использует http
вместо https
, Попробуйте изменить URL файла, который вы пытаетесь вставить https
,
Например:
var id = getId(url);
return '//www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
}
быть:
var id = getId(url);
return 'https://www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
}
Просто добавьте параметр "origin"
с URL вашего сайта в paramVars
Атрибут игрока, вот так:
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' },
}
Установка это, кажется, исправить это:
this$1.player = new YouTube.Player(this$1.elementId, {
videoId: videoId,
host: 'https://www.youtube.com',
Вы можете сохранить в локальные файлы:
- https://www.youtube.com/player_api
- https://s.ytimg.com/yts/jsbin/www-widgetapi-vfluxKqfs/www-widgetapi.js
В первый файл 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
PS: Извините, английский не мой первый язык.
В моем случае это было связано с ленивой загрузкой iframe. Удаление HTML-атрибута iframe
loading="lazy"
решил проблему для меня.
Убедитесь, что вы загружаете с URL-адреса, такого как:
Обратите внимание на компонент "origin", а также "enablejsapi=1". Источник должен соответствовать вашему домену, а затем он будет внесен в белый список и будет работать.
Я получил ту же ошибку. Моя ошибка заключалась в том, что enablejsapi=1
параметр не присутствовал в iframe
ЦСИ.
Вы также получаете это сообщение, если не указываете targetOrigin в вызовахwindow.postMessage()
.
В этом примере мы отправляем сообщение в первый iFrame и используем *
как цель, которая должна обеспечивать связь с любым targetOrigin.
window.frames[0].postMessage({
message : "Hi there",
command :"hi-there-command",
data : "Some Data"
}, '*')
Похоже, что это всего лишь система безопасности Chrome, которая блокирует повторяющиеся запросы с помощью CORB.
https://www.chromestatus.com/feature/5629709824032768
В моем случае YouTube блокировал доступ после первой загрузки той же веб-страницы, которая имеет много запросов данных видео API, высокую полезную нагрузку.
Для страниц с низкой полезной нагрузкой проблема не возникает.
В Safari и других браузерах, не основанных на Chronuim, проблема не возникает.
Если я загружаю веб-страницу в новом браузере, проблема не возникает, когда я перезагружаю ту же страницу, проблема появляется.
Попробуйте использовать window.location.href
для URL, чтобы соответствовать происхождению окна.
Расширение ответа @Hokascha выше также было ленивой загрузкой для меня, автоматически добавленным WordPress. Этот код удалит всю ленивую загрузку в фреймах сайта (добавьте в functions.php):
function disable_post_content_iframe_lazy_loading( $default, $tag_name, $context ) {
if ( 'iframe' === $tag_name ) {
return false;
}
return $default;
}
add_filter('wp_lazy_loading_enabled', 'disable_post_content_iframe_lazy_loading', 10, 3);
Удаление DNS Prefetch решит эту проблему.
Если вы используете WordPress, добавьте эту строку в functions.php вашей темы
remove_action( 'wp_head', 'wp_resource_hints', 2 );
Может быть что-то из следующего, но все они приводят к тому, что DOM не загружается до того, как к нему обращается javascript.
Итак, вот что вы должны убедиться перед фактическим вызовом JS-кода: * Убедитесь, что контейнер загружен, прежде чем будет вызван какой-либо javascript * Убедитесь, что целевой URL загружен в любой контейнер, который он должен
Я столкнулся с аналогичной проблемой, но на моем локальном компьютере, когда я пытаюсь запустить свой Javascript задолго до onLoad главной страницы, которая вызывает сообщение об ошибке. Я исправил это, просто дождавшись загрузки всей страницы, а затем вызвал требуемую функцию.
Вы можете просто сделать это, добавив функцию тайм-аута, когда страница загружена, и вызвать событие onload, например:
window.onload = new function () {setTimeout(function() {// какое-то событие загрузки}, 10); }
Это гарантирует, что то, что вы пытаетесь, будет хорошо выполняться после срабатывания onLoad.
В моем случае, по крайней мере, это безобидное условие "не готов", когда API повторяет попытки, пока не добьется успеха.
Я получаю от двух до девяти таких (на моем тестере в наихудшем случае, FossilBook 2009 года с 20 вкладками, открытыми через точку доступа сотовой связи).... но тогда видео работает правильно. Как только он запускает мои вызовы на основе postMessage, чтобы seekTo определенно работал, другие не тестировали.
Это помогло мне (с 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,
},
};
},
В некоторых случаях (как упомянул один из комментаторов) это может быть вызвано перемещением игрока внутри DOM, например append
или т.д..
Я получил похожее сообщение об ошибке при попытке встроить таблицу цен Stripe, когда:
Добавление кода для встраивания через PHP с помощью пользовательского короткого кода WordPress
Или путем динамического добавления кода на страницу с помощью JavaScript (даже при использовании
setTimeout()
задержка для обеспечения загрузки DOM не работает).
Я смог решить эту проблему на своем сайте WordPress, добавив код на саму страницу WordPress, используя простой html-код в редакторе блоков.
Я думаю, что описание ошибки вводит в заблуждение и изначально связано с неправильным использованием объекта player.
У меня была такая же проблема при переключении на новые видео в слайдере.
Когда просто с помощью player.destroy()
описанная здесь функция исчезла.
я используюThe Angular Youtube component
вот что они сказали об этой ошибке времени выполнения: т.е. решения пока нет.
Я тоже иногда видел это в нашем приложении для разработчиков, но не думаю, что мы можем что-то с этим поделать, поскольку это происходит из кода YouTube, изолированного внутри iframe.
Ссылка: https://github.com/angular/comComponents/issues/22835#issuecomment-853176948 .
Просто желая избежать ошибки консоли, я решил это, используя подход, аналогичный предыдущему ответу Артура, выполнив следующие действия:
- Загрузил YouTube Iframe API (с https://www.youtube.com/iframe_api) в локальный файл yt-api.js.
- Удален код, который вставлял скрипт www-widgetapi.js.
- Загрузил скрипт www-widgetapi.js (с https://s.ytimg.com/yts/jsbin/www-widgetapi-vfl7VfO1r/www-widgetapi.js) в локальный файл www-widgetapi.js.
- Заменен аргумент targetOrigin в вызове postMessage, который вызывал ошибку в консоли, на "*" (что указывает на отсутствие предпочтений - см. https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
- Добавил измененный сценарий www-widgetapi.js в конец сценария yt-api.js.
Это не лучшее решение (исправленный локальный скрипт для поддержки, потеря контроля над отправкой сообщений), но это решило мою проблему.
Пожалуйста, ознакомьтесь с предупреждением системы безопасности об удалении указанного здесь URI targetOrigin перед использованием этого решения - https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
У меня была такая же проблема, и оказалось, что это потому, что у меня запущено расширение Chrome "HTTPS Everywhere". Отключение расширения решило мою проблему.
Эта точная ошибка была связана с блокировкой контента Youtube при "воспроизведении на определенных сайтах или в приложениях". В частности, от WMG (Warner Music Group).
Однако в сообщении об ошибке указывалось, что проблема заключается в импорте iframe https на сайт http, чего не было в данном случае.
Вы можете изменить свой iframe таким образом, чтобы он добавлял origin в качестве текущего сайта. Это устраняет ошибку в моем браузере.
<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
Добавление
origin=${window.location.host} or "*"
недостаточно.
Добавить
https://
перед этим и будет работать.
Кроме того, убедитесь, что вы используете URL-адрес, который можно встроить: выньте идентификатор видео и объедините строку с префиксом видео YouTube и определением идентификатора видео + встраивание.
Я использую Google Chrome, и у меня была такая же проблема в течение нескольких дней. Затем я понял, что ошибка возникла только тогда, когда я использовал атрибут списка воспроизведения для принудительного воспроизведения в цикле. Поэтому я удалил атрибут списка воспроизведения и использовал метод onStateChange, чтобы возобновить воспроизведение. Если вы когда-нибудь столкнулись с этой проблемой и у вас есть атрибут списка воспроизведения, стоит проверить, является ли он причиной.
Я думаю, мы могли бы настроить sendMessage для YT.Player.
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)
}
}
Я использовал эту функцию для разрешения в моем проекте.
Можешь попробовать:
document.getElementById('your_id_iframe').contentWindow.postMessage('your_message', 'your_domain_iframe')
Мой был:
<youtube-player
[videoId]="'paxSz8UblDs'"
[playerVars]="playerVars"
[width]="291"
[height]="194">
</youtube-player>
Я просто удалил строку с playerVars, и на консоли она работала без ошибок.
Я также столкнулся с той же проблемой, когда я зашел на официальный Youtube Iframe Api, где я нашел это:
Браузер пользователя должен поддерживать функцию HTML5 postMessage. Большинство современных браузеров поддерживают postMessage
и прогуляйтесь, чтобы увидеть, что эта официальная страница также сталкивается с этой проблемой. Просто посетите официальный Youtube Iframe Api и просмотрите журналы консоли. Моя версия Chrome - 79.0.3945.88.