javascript - Komma åt förälderns URL från iframe
Okej, jag har en sida och på den här sidan har jag en iframe. Vad jag behöver göra är att på iframe-sidan ta reda på vad URL:en till huvudsidan är.
Jag har letat runt och jag vet att detta inte är möjligt om min iframe-sida ligger på en annan domän, eftersom det är cross-site scripting. Men överallt jag har läst står det att om iframe-sidan är på samma domän som föräldrasidan, borde det fungera om jag till exempel gör:
parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href
... eller andra liknande kombinationer, eftersom det verkar finnas flera sätt att få samma information.
Hur som helst, så här är problemet. Min iframe är på samma domän som huvudsidan, men den är inte på samma SUB-domän. Så till exempel har jag
http://www.mysite.com/pageA.html
och sedan är min iframe-URL
http://qa-www.mysite.com/pageB.html
När jag försöker hämta URL:en från pageB.html (iframe-sidan) får jag hela tiden samma åtkomst nekad-fel. Så det verkar som att även subdomäner räknas som cross-site-scripting, är det korrekt, eller gör jag något fel?
Svar #1
Ja, åtkomst till föräldrasidans URL är inte tillåten om iframe och huvudsidan inte är i samma (sub)domän. Men om du bara behöver URL:en till huvudsidan (dvs. webbläsarens URL) kan du prova detta:
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
Notera:
window.parent.location är tillåtet; det undviker säkerhetsfelet i OP, vilket orsakas av att man försöker komma åt href-egenskapen: window.parent.location.href orsakar "Blocked a frame with origin..."
document.referrer refererar till "URI:n för sidan som länkade till denna sida." Detta kanske inte returnerar det omfattande dokumentet om någon annan källa är vad som bestämde iframe-platsen, till exempel:
- Container iframe @ Domän 1
- Skickar barn-iframe till Domän 2
- Men i barn-iframe... Omdirigerar Domän 2 till Domän 3 (dvs. för autentisering, kanske SAML), och sedan leder Domän 3 tillbaka till Domän 2 (dvs. via formulärinlämning(), en standard SAML-teknik)
- För barn-iframe kommer
document.referreratt vara Domän 3, inte den innehållande Domän 1
document.location avser "ett Location-objekt, som innehåller information om URL:en för dokumentet"; förmodligen det aktuella dokumentet, det vill säga det iframe som för närvarande är öppet. När window.location === window.parent.location, då är iframens href densamma som den innehållande förälderns href.
Svar #2
Jag har precis upptäckt en lösning på detta problem som är så enkel, och ändå har jag inte hittat några diskussioner någonstans som nämner det. Det kräver dock kontroll över moderfönstret.
I din iFrame, säg att du vill ha denna iframe: src="http://www.example.com/mypage.php"
Tja, istället för att använda HTML för att specificera iframe, använd JavaScript för att bygga HTML för din iframe, hämta förälderns URL via JavaScript "vid byggtid" och skicka den som en URL GET-parameter i frågesträngen för ditt src-mål, på följande sätt:
<script type="text/javascript">
url = parent.document.URL;
document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>
Sedan, hitta en JavaScript-funktion för URL-parsing som analyserar URL-strängen för att få den URL-variabel du är ute efter, i det här fallet är det "url".
Jag hittade en bra url-strängparser här: http://www.netlobo.com/url_query_string_javascript.html
Svar #3
Följande rad fungerar: document.location.ancestorOrigins[0] denna returnerar den överordnade domänens namn.
Svar #4
Om din iframe är från en annan domän (cross domain) behöver du helt enkelt använda detta:
var currentUrl = document.referrer;
och - här har du huvud-URL:en!
Svar #5
Du har rätt. Subdomäner betraktas fortfarande som separata domäner när man använder iframes. Det är möjligt att skicka meddelanden med postMessage(...), men andra JS-API:er är avsiktligt gjorda otillgängliga.
Det är fortfarande möjligt att få URL:en beroende på sammanhanget. Se andra svar för fler detaljer.
Svar #6
För sidor på samma domän och olika subdomän kan du ställa in document.domain-egenskapen via javascript.
Både föräldraramen och iframe måste ställa in sitt document.domain till något som är gemensamt mellan dem.
dvs. www.foo.mydomain.com och api.foo.mydomain.com kan vardera använda antingen foo.mydomain.com eller bara mydomain.com och vara kompatibla (nej, du kan inte sätta båda till com, av säkerhetsskäl...)
Notera också att document.domain är en envägsgata. Överväg att köra följande tre uttalanden i ordning:
// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception
Moderna webbläsare kan också använda window.postMessage för att kommunicera över ursprung, men det fungerar inte i IE6. https://developer.mozilla.org/en/DOM/window.postMessage
Svar #7
Det finns många svar på den här frågan, och inget av dem är definitivt det bästa när det gäller stöd eller pålitlighet.
Alternativ
window.location.ancestorOrigins[0]hämtar förälderns URL, men detta API fungerar endast i Chromium-webbläsare (se stöd). Detta stöder även inbäddade iframes, där det nedersta barnet har tillgång till URL:erna för varje föräldra-iframe.document.referrerär det vanligaste svaret men är inte alltid pålitligt- navigering inne i iframe skulle visa den senaste sidan istället för förälderrammans URL
- omdirigeringar visar endast den senaste refereraren till den aktuella sidan
- om sidan laddas om själv blir refereraren sidan själv
- http-barn med en https-förälder har en tom sträng för hänvisare
Saker som inte fungerar
window.parent.location.href. Om föräldern och barnet är på olika domäner, blockeras denna API av moderna webbläsare (se här), och kommer att kasta ett fel.
Rekommendation
Om det stöds föredrar jag window.location.ancestorOrigins[0]. document.referrer kan fungera, men är mindre pålitligt, vilket gör det till mitt reservalternativ. Om du använder document referrer, försök att anropa det vid den första inramade sidans laddning, innan navigering eller omdirigeringar, för att få förälderns adress.
Svar #8
Prova det:
document.referrer
När du ändrar att du är i en iframe är din värd "referrer".
