2015-01-11 4 views
2

Я извиняюсь перед тем, как меня очень смущает моя проблема. Я действительно привязан, потому что это вызывает проблемы на моем рабочем сайте.Не удалось выполнить «postMessage» в «DOMWindow»: несоответствие цели/происхождения http vs https

У меня есть javascript-плеер на моем сайте, который воспроизводит списки песен, которые могут быть размещены на youtube, soundcloud или vimeo. Вчера я заметил эту ошибку, которая обычно возникает в любое время, когда вы пытаетесь загрузить новую песню с помощью «пропусков» с помощью кнопок проигрывателя. Эта ошибка только началась в последние сутки или два. Я не вижу ничего нового в примечаниях к выпуску youtube api, и эта ошибка возникает с использованием Chrome, Firefox и Safari, поэтому, скорее всего, это не связано с изменением в браузере. Что-то, что я использую, изменилось, так как я не подтолкнул новый код за 18 дней.

Пример списка воспроизведения здесь: http://www.muusical.com/playlists/programming-music

Я думаю, что изолировали способ воспроизвести ошибку, вот шаги:

  1. Сыграйте YouTube прошла песню.
  2. Пропустить и перейти к следующей песне в списке (нажав кнопку пропуска или нажав кнопку воспроизведения в элементе строки песни).

* Обратите внимание, что если первая песня в плейлисте - это песня youtube, просто переход к другой песне даже без воспроизведения первоначально загруженной песни YouTube приведет к ошибке.

По сути, ошибка возникает, если вы загрузили и/или воспроизвели песню на 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&amp;enablejsapi=1&amp;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 загружена, «происхождение» изменяется с http на https. Я не думаю, что необходимо включить методы внедрения других хостов, поскольку эта ошибка возникает, даже если весь плейлист является только youtube, и это не происходит в плейлисте, который состоит только из песен из soundcloud и vimeo.

Кроме того, это, как я загрузке 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); 

Пожалуйста, дайте мне знать, если вам нужно мне прояснить что-либо и заранее спасибо за то посмотреть.

ответ

1

@ ответ sodawillow является частично правильным, но я хотел бы дать подробную информацию об этом решении и что заставило мой код прекратить вызов метода .destroy() для удаления проигрывателя YouTube.

На моем сайте есть плеер, который меняет песни с разных сайтов, одним из которых является Youtube. Могут быть разные методы для удаления игрока в зависимости от типа. Мой код проверяет наличие проигрывателя YouTube, и если он проходит проверку, то он использует метод .destroy(), который имеет только проигрыватель youtube. Проблема заключается в том, что 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, изменив расположение некоторых статических переменных.

2

Я прочитал немного об этом, некоторые SO посты здесь и там, и это тоже ссылка: https://code.google.com/p/gdata-issues/issues/detail?id=5788

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

Я начинаю с пустого элемента div и использую Youtube Iframe API, чтобы превратить его в iframe со всеми необходимыми параметрами.

У меня есть несколько div, как этот, и обычно используют одну и ту же переменную JS для хранения всех этих игроков, но по одному (один заменяет другой и т. Д.) - это может быть лучше, я знаю).

Чтобы исправить проблему, у меня возникла идея: уничтожить игрока с youtubePlayer.destroy(); перед тем, как построить новый из другого элемента. Больше нет ошибок JS в моей консоли Chrome :).

Надеется, что это помогает, все Littérature я мог прочитать о HTTP и HTTPS не относится к моему делу, потому что я не установкам IFrame URL-адресу самому, и мой сайт случается не HTTPS ...

Я действительно восстановил асинхронный вызов вместо статического тега script в своем HTML, но я не думаю, что это было необходимо.

EDIT: это сообщение об ошибке достаточно ввести в заблуждение на самом деле, это лишь смутно означает: вы не используете YouTube API надлежащим образом :)

+0

Благодарим за отзыв! Я действительно запускаю метод destroy() на проигрывателе, когда избавляюсь от него, но на самом деле я не прочитал все обсуждения в указанной вами ссылке. Я пробовал различные комбинации настройки http/https в начале или нет и динамически загружаемый скрипт, но я рассмотрю эту дискуссию немного научнее и, надеюсь, это наконец даст. :) – wuliwong

+0

Какие из ваших проектов у вас были проблемы? Похоже, у вас есть несколько музыкальных сайтов с игроками. :) – wuliwong

+0

Вы на самом деле пошли на мой сайт lol :) Не знаю, стоит ли публиковать его здесь, но эй ... он уже в сети :) http://manec.fr: каждый раз, когда вы попадаете на планету, вы открываете раздел с другим проигрывателем YouTube (внизу справа) – sodawillow

0

Мое решение состоит в том, чтобы написать всю логику проигрывателя 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/)

1

Эта ошибка относится к API Google Youtube.

Внутри "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.

Нам нужно переопределить параметр «хост», а «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" 
} 

Goodluck.

Смежные вопросы