Nie udało się wykonać „postMessage” w „DOMWindow”: https://www.youtube.com! == http: // localhost: 9000

167

Oto komunikat o błędzie, który otrzymuję:

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').

Widziałem inne podobne problemy, w których znajduje się źródło docelowe http://www.youtube.comi źródło odbiorcy https://www.youtube.com, ale żaden nie przypomina mojego, gdzie jest cel https://www.youtube.comi źródło jest http://localhost:9000.

  1. Nie mam problemu. Jaki jest problem?
  2. Jak mogę to naprawić?
Adam Zerner
źródło
4
Miałem ten sam problem, a poprawka poniżej autorstwa @ChrisFranklin naprawiła go dla mnie; ale dziwne jest to, że z moim problemem otrzymywałem błąd tylko w połowie czasu, a nawet wtedy wideo nadal się ładowało (chociaż inne rzeczy się zepsuły).
dgo
1
@dgo ten sam problem, był losowy podczas ładowania strony. Okazuje się (myślę), że jest to spowodowane faktyczną zawartością elementu iframe, która nie jest w pełni gotowa do czasu, gdy coś innego próbuje wysłać wiadomość. Więc to stan wyścigu. A jeśli postMessage nastąpi później (akcja użytkownika), działa dobrze bez błędów.
IncredibleHat
nawet Google ma sam ten błąd - otwórz konsolę i odtwórz wideo tutaj: developers.google.com/youtube/iframe_api_reference
T.Todua

Odpowiedzi:

92

Uważam, że jest to problem z docelowym pochodzeniem https. Podejrzewam, że dzieje się tak, ponieważ Twój adres URL iFrame używa httpzamiast https. Spróbuj zmienić adres URL pliku, który próbujesz osadzić https.

Na przykład:

'//www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';

być:

'https://www.youtube.com/embed/' + id + '?showinfo=0&enablejsapi=1&origin=http://localhost:9000';
Chris Franklin
źródło
2
Wygląda na to, że zadziałało. Dzięki! Więc problem jest httpvs. https? Nie ma znaczenia, że ​​domeny się różnią (youtube vs. localhost)? A czym dokładnie jest pochodzenie docelowe w porównaniu do pochodzenia odbiorcy? Jak zmieniłeś pochodzenie odbiorcy (mój adres URL to nadal localhost: 9000)?
Adam Zerner
30
Błąd jest trochę mylący. W rzeczywistości nie ma to nic wspólnego z tym, że jesteś włączony localhost:9000. Problem polegał w rzeczywistości na sposobie korzystania z interfejsu youtube-api. Deklarując api tak, jak tag.src = "https://www.youtube.com/iframe_api";w kodzie, mówisz youtube, że chcesz używać ssl. Tak więc zmiana, którą zasugerowałem, zmieniła cię na używanie SSL do żądania filmów. Błąd był po prostu informacją, że mieszasz wywołania SSL i inne niż SSL.
Chris Franklin,
9
Natknąłem się na ten problem, gdy próbowałem przesuwać ramkę iframe w dom. playerEl = document.querySelector('iframe#ytplayer'); anotherEl.appendChild(playerEl); // yt complains on subsequent api calls
posit labs
1
co, jeśli używam javascript do ładowania odtwarzacza YouTube?
N3R4ZZuRR0
5
zmieniono na https: // dla youtube, a moja domena to https: // nadal nie rozwiązuje mojego problemu. Nie udało się wykonać „postMessage” w „DOMWindow”: podane źródło docelowe („ youtube.com ”) nie jest zgodne z miejscem pochodzenia okna odbiorcy („ test.dev ”).
vee
24

Po prostu dodaj parametr "origin"z adresem URL swojej witryny do paramVarsatrybutu odtwarzacza, na przykład:

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' },
}
Flávio
źródło
7
origin: window.location, we właściwościach obejmujących tworzenie i produkcję
James Bailey
3
@JamesBailey window.location.origin.. window.locationto obiekt.
Acidic9
Jak mówi dokument API, origin playerVar jest używany tylko z czystą implementacją iframe. Nie JS API.
Damien C
1
Wszystkie te „poprawki” nie działają dla nas tutaj w 2020 r. Ponadto, aby dodać, losowe ładowanie na stronę, gdy pojawia się błąd. To warunek wyścigu między naszą witryną a YouTube.
IncredibleHat
window.location.host
LeeGee
19

Wydaje się, że ustawienie tego rozwiązuje problem:

  this$1.player = new YouTube.Player(this$1.elementId, {
    videoId: videoId,
    host: 'https://www.youtube.com',
M.Ali El-Sayed
źródło
3
zrobienie tego http (zamiast https) rozwiązało mój problem.
T.Todua
5
To również naprawiło to dla mnie. Można również zrobić: host: `${window.location.protocol}//www.youtube.com`,
Joel Worsham
2
Wszystkie te „poprawki” nie działają dla nas tutaj w 2020 r. Ponadto, aby dodać, losowe ładowanie na stronę, gdy pojawia się błąd. To warunek wyścigu między naszą witryną a YouTube.
IncredibleHat
8

Możesz zapisać JavaScript w lokalnych plikach:

W pierwszym pliku player_apiumieść ten kod:

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])}}());

W drugim pliku znajdź kod: this.a.contentWindow.postMessage(a,b[c]);

i zamień na:

if(this._skiped){
    this.a.contentWindow.postMessage(a,b[c]); 
}
this._skiped = true;

Oczywiście można połączyć w jeden plik - będzie bardziej wydajne. To nie jest idealne rozwiązanie, ale działa!

Moje źródło: yt_api-concat

Artur
źródło
Naprawiłem to dla mnie. Miałem pliki lokalnie, więc pasuj do mojego przypadku użycia.
częste
U mnie też to zadziałało, ale nie wiem dlaczego. Czy możesz wyjaśnić, dlaczego to rozwiązuje problem?
jchavannes
1
dziękuję, odpowiedziałem na moje pytanie przy drugim połączeniu Ajax: stackoverflow.com/questions/58232081/…
Diogo Almeida
Z mojego punktu widzenia używanie lokalnego pliku dla biblioteki, w szczególności dla biblioteki usług stron trzecich, jest bardzo złym sposobem na kodowanie. Nie?
Damien C
@DamienC Na pewno nie jest to idealne rozwiązanie. Ale biorąc pod uwagę wszystkie inne „poprawki” w tym wątku, nie jestem zaskoczony (ani nie oceniam) innych programistów, którzy ręcznie zmieniają kod API.
Erutan409
3

Spróbuj użyć window.location.hrefadresu URL, aby dopasować pochodzenie okna.

Chaitanya Shah
źródło
Świetnie, wypróbowałem wszystkie inne odpowiedzi i to zadziałało!
Kloshar4o
3

Mam ten sam błąd. Mój błąd polegał na tym, że enablejsapi=1parametr nie był obecny w iframesrc.

zdrowaśka
źródło
0

Myślę, że opis błędu jest mylący i pierwotnie dotyczy złego użycia obiektu gracza.

Miałem ten sam problem podczas przełączania się na nowe filmy w suwaku.

Po prostu przy użyciu player.destroy()funkcji opisanej tu problem znika.

denns
źródło
Czy możesz sprawdzić, czy rozumiesz, czego doświadczam tutaj w YouTube i czy jest to powiązane? stackoverflow.com/q/57649870/470749 Może będziesz miał odpowiedź. Dzięki!
Ryan
0

Miałem ten sam problem i okazuje się, że było to spowodowane uruchomionym rozszerzeniem Chrome „HTTPS Everywhere”. Wyłączenie rozszerzenia rozwiązało mój problem.

Gavin
źródło
0

Dokładnie ten błąd był związany z blokowaniem treści przez YouTube podczas „odtwarzania w niektórych witrynach lub aplikacjach”. Dokładniej przez WMG (Warner Music Group).

Komunikat o błędzie sugerował jednak, że problemem był import elementu iframe https do witryny http, czego nie było w tym przypadku.

TomSjogren
źródło
0

Usuń DNS Prefetch rozwiąże ten problem.

Jeśli korzystasz z WordPressa, dodaj ten wiersz do pliku functions.php swojego motywu

remove_action( 'wp_head', 'wp_resource_hints', 2 );
Terry Lin
źródło
0

Możesz zmienić element iframe na taki i dodać źródło do bieżącej witryny internetowej. Rozwiązuje to błąd w mojej przeglądarce.

<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>

ref: https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

nhật tài nguyễn
źródło
0

Może istnieć dowolna z poniższych sytuacji, ale wszystkie prowadzą do DOM, który nie został załadowany przed uzyskaniem do niego dostępu przez skrypt javascript.

Oto, co musisz upewnić się, zanim faktycznie wywołasz kod JS: * Upewnij się, że kontener został załadowany przed wywołaniem jakiegokolwiek kodu JavaScript * Upewnij się, że docelowy adres URL jest załadowany do dowolnego kontenera, który ma

Natknąłem się na podobny problem, ale na moim lokalnym, gdy próbuję uruchomić mój Javascript na długo przed onLoad strony głównej, co powoduje komunikat o błędzie. Naprawiłem to, po prostu czekając na załadowanie całej strony, a następnie wywołując wymaganą funkcję.

Możesz to po prostu zrobić, dodając funkcję limitu czasu po załadowaniu strony i wywołać zdarzenie onload, takie jak:

window.onload = new function () {setTimeout (function () {// jakieś zdarzenie onload}, 10); }

to zapewni, że to, co próbujesz, zostanie wykonane dobrze po wyzwoleniu onLoad.

KMX
źródło
Włożenie wszystkiego do środka document.addEventListener("DOMContentLoaded", function () {niestety nie pomogło.
Ryan
0

Ten komunikat jest również wyświetlany, gdy nie określisz targetOrigin w wywołaniach funkcji window.postMessage().

W tym przykładzie wysyłamy wiadomość do pierwszego elementu iFrame i używamy go *jako celu, co powinno pozwolić na komunikację z dowolnym targetOrigin.

window.frames[0].postMessage({
                    message : "Hi there",
                    command :"hi-there-command",
                    data : "Some Data"
                }, '*')
LukeSolar
źródło
0

W moim przypadku przynajmniej wydaje się to nieszkodliwym warunkiem „niegotowym”, że API ponawia próby, aż się powiedzie.

Dostaję od dwóch do dziewięciu z nich (na moim testerze najgorszych przypadków, FossilBook 2009 z 20 otwartymi zakładkami przez hotspot komórkowy) ... ale wtedy wideo działa poprawnie. Po uruchomieniu moich wywołań opartych na postMessage do seekTo zdecydowanie działa, nie testowałem innych.

Roger Krueger
źródło
0

W niektórych przypadkach (jak wspomniał jeden z komentatorów) może to być spowodowane przenoszeniem odtwarzacza w ramach DOM, np. appendItp.

T.Todua
źródło
-1

Możesz spróbować :

document.getElementById('your_id_iframe').contentWindow.postMessage('your_message', 'your_domain_iframe')
HoaTruong
źródło
-1

Miałem również ten sam problem, a potem odwiedziłem oficjalny interfejs YouTube Iframe Api, gdzie znalazłem to:

Przeglądarka użytkownika musi obsługiwać funkcję postMessage HTML5. Większość nowoczesnych przeglądarek obsługuje postMessage

i wędruj, aby zobaczyć, że ta oficjalna strona również została dotknięta tym problemem. Po prostu odwiedź oficjalny interfejs API iframe w serwisie Youtube i zobacz dzienniki konsoli. Moja wersja Chrome to 79.0.3945.88.

Shahbaz Shoukat
źródło
-2

Moje było:

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

Właśnie usunąłem linię z playerVars i działało bez błędów na konsoli.

Gabriel Alcântara
źródło