Не удалось выполнить «postMessage» в «DOMWindow»: https://www.youtube.com! == http: // localhost: 9000


168

Это сообщение об ошибке, которое я получаю:

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 устранило ее для меня; но что странно, так это то, что с моей проблемой я получаю сообщение об ошибке только половину времени, и даже тогда видео все равно будет загружаться (хотя другие вещи могут сломаться).
августа

1
@dgo та же проблема, это было случайно при загрузке страницы. Оказывается (я думаю), это связано с тем, что фактическое содержимое iframe еще не полностью готово к тому времени, когда что-то еще пытается сделать postMessage. Так что это состояние гонки. И если postMessage происходит позже (действие пользователя), он работает без ошибок.
НевероятноHat

даже у Google есть такая ошибка: откройте консоль и
посмотрите

Ответы:


92

Я считаю, что это проблема с целевым происхождением 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';

2
Кажется, это сработало. Спасибо! Таким образом, проблема httpпротив https? Неважно, что домены отличаются (YouTube против localhost)? И что именно является целевым происхождением против получателя? Как то, что вы сказали, изменило происхождение получателя (мой URL все еще localhost: 9000)?
Адам Зернер

30
Ошибка немного вводит в заблуждение. Это на самом деле не имеет никакого отношения к тому, что вы находитесь на localhost:9000. Проблема была в том, как вы использовали API-интерфейс YouTube. Когда вы объявляете API как tag.src = "https://www.youtube.com/iframe_api";в своем коде, вы говорите YouTube, что хотите использовать ssl. Таким образом, предложенные мной изменения позволили вам использовать ssl для запроса видео. Ошибка просто говорила, что вы смешиваете ssl и non-ssl вызовы.
Крис Франклин

9
Я столкнулся с этой проблемой, когда попытался переместить iframe в дом. playerEl = document.querySelector('iframe#ytplayer'); anotherEl.appendChild(playerEl); // yt complains on subsequent api calls
Позит лаборатории

1
Что делать, если я использую JavaScript для загрузки плеера YouTube?
N3R4ZZuRR0

5
изменил на https: // для YouTube, и мой домен https: // до сих пор не решил мою проблему. Не удалось выполнить 'postMessage' в 'DOMWindow': предоставленный целевой источник (' youtube.com ') не соответствует источнику окна получателя (' test.dev ').
ви

24

Просто добавьте параметр "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' },
}

7
Происхождение: window.location, в свойствах для разработки и производства
Джеймс Бэйли,

3
@JamesBailey window.location.origin.. window.locationэто объект.
Acidic9

Как говорит API-документ, origin Player использует только чистую реализацию iframe. Не JS API один.
Дэмиен C

1
Все эти «исправления» не работают для нас здесь, в 2020 году. Также добавим, что их случайная загрузка страницы при появлении ошибки. Это условие гонки между нашим сайтом и YouTube.
НевероятноHat

window.location.host
LeeGee

19

Установка это, кажется, исправить это:

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

3
сделать это http (вместо https) решил мою проблему.
Т.Тодуа

5
Это исправило это и для меня. Можно также сделать: host: `${window.location.protocol}//www.youtube.com`,
Джоэл Worsham

2
Все эти «исправления» не работают для нас здесь, в 2020 году. Также добавим, что их случайная загрузка страницы при появлении ошибки. Это условие гонки между нашим сайтом и YouTube.
НевероятноHat

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/…
Диого Алмейда

На мой взгляд, использование локального файла для библиотеки, в частности для сторонней сервисной библиотеки, является очень плохим способом кодирования. Нет?
Дэмиен С

@DamienC Это далеко не идеально, конечно. Но, основываясь на всех других «исправлениях» в этом потоке, я не удивлен (и я действительно не осуждаю) других разработчиков, изменяющих код API вручную.
Erutan409

5

Убедитесь, что вы загружаете с 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. Источник должен соответствовать вашему домену, и тогда он будет в белом списке и будет работать.


3

Попробуйте использовать window.location.hrefдля URL, чтобы соответствовать происхождению окна.


Хорошо, я попробовал все остальные ответы, и это сработало для меня!
Kloshar4o

3

Я получил ту же ошибку. Моя ошибка состояла в том, что enablejsapi=1параметр не присутствовал в iframesrc.


0

Я думаю, что описание ошибки вводит в заблуждение и изначально связано с неправильным использованием объекта player.

У меня была такая же проблема при переключении на новые видео в слайдере.

При простом использовании player.destroy()функции, описанной здесь, проблема исчезла.


Не могли бы вы посмотреть, если вы понимаете, что я испытываю на YouTube здесь и связано ли это? stackoverflow.com/q/57649870/470749 Возможно, у вас будет ответ. Спасибо!
Райан

0

У меня была такая же проблема, и оказалось, что это потому, что у меня было запущено расширение Chrome "HTTPS Everywhere". Отключение расширения решило мою проблему.


0

Эта точная ошибка была связана с блокировкой контента Youtube при «воспроизведении на определенных сайтах или в приложениях». В частности, от WMG (Warner Music Group).

Однако в сообщении об ошибке указывалось, что проблема заключается в импорте iframe https на сайт http, чего в данном случае не было.


0

Удаление DNS Prefetch решит эту проблему.

Если вы используете WordPress, добавьте эту строку в functions.php вашей темы

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

0

Вы можете изменить свой 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


0

Может быть любое из следующего, но все они ведут в DOM, не загруженный до того, как к нему обращается javascript.

Итак, вот что вы должны убедиться перед фактическим вызовом кода JS: * Убедитесь, что контейнер загружен до вызова любого javascript * Убедитесь, что целевой URL загружен в любой контейнер, который он должен

Я сталкивался с подобной проблемой, но на моем локальном компьютере, когда я пытаюсь запустить мой Javascript задолго до onLoad главной страницы, что вызывает сообщение об ошибке. Я исправил это, просто ожидая загрузки всей страницы и затем вызывая требуемую функцию.

Вы можете просто сделать это, добавив функцию тайм-аута, когда страница загрузится, и вызвать событие onload, например:

window.onload = new function () {setTimeout (function () {// некоторое событие загрузки), 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 повторяет до тех пор, пока не выполнится успешно.

Я получаю от двух до девяти из них (на моем тестере наихудшего случая, FossilBook 2009 года с 20 вкладками, открытыми через сотовую точку доступа) ... но тогда видео работает нормально. Как только он запускает мои вызовы на основе postMessage для поиска, чтобы определенно работать, не проверял других.


0

В некоторых случаях (как упомянул один комментатор) это может быть вызвано тем, что вы перемещаете игрока в DOM, например, appendили т. Д.


-1

Можешь попробовать :

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

-1

Я также столкнулся с той же самой проблемой, тогда я захожу на официальный YouTube Iframe Api, где я нашел это:

Браузер пользователя должен поддерживать функцию HTML5 postMessage. Большинство современных браузеров поддерживают postMessage

и побродить, чтобы увидеть, что официальная страница также сталкивается с этой проблемой Просто зайдите на официальный Youtube Iframe Api и посмотрите логи консоли. Моя версия Chrome 79.0.3945.88.


-2

мой был:

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

Я просто удалил строку с playerVars, и она работала без ошибок на консоли.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.