Bu nasıl:
[ Kasım 2020 Güncellemesi: Bu çözüm, ayarlanabilmeye dayanıyor document.domain
. Bunu yapma yeteneği maalesef artık kullanımdan kaldırıldı. ]
Belirli bir üst alan adının (örneğin, ornek.com) alt alanları arasında paylaşım için, bu durumda kullanabileceğiniz bir teknik vardır. Uygulanabilir localStorage
, IndexedDB
, SharedWorker
, BroadcastChannel
, vb aynı kaynak sayfaları arasında paylaşılan işlevsellik sunan, ama nedense herhangi bir değişiklik saygı göstermeyen her biri document.domain
onları doğrudan kendi kökeni olarak üst etki kullanmasına izin söyledi.
(1) Verilerin ait olması için bir "ana" alan seçin: yani https://example.com veya https://www.example.com localStorage verilerinizi tutacaktır. Diyelim ki https: //example.com'u seçtiniz .
(2) LocalStorage'ı o seçilen etki alanının sayfaları için normal olarak kullanın.
(3) Tüm https://www.example.com sayfalarında ( diğer alan), ayarlamak için javascript kullanın document.domain = "example.com";
. Sonra da bir gizli oluşturmak <iframe>
ve bunu gezinmek bazı seçilmiş sayfa https://example.com (etki O önemli değil neyi sayfa sürece orada javascriptle çok küçük parçacığını ekleyebilirsiniz olarak. Eğer' siteyi yeniden oluştururken, özellikle bu amaç için boş bir sayfa yapın. Bir uzantı veya Greasemonkey tarzı bir kullanıcı yazısı yazıyorsanız ve bu nedenle example.com'daki sayfalar üzerinde herhangi bir kontrolünüz yoksasunucuda bulabileceğiniz en hafif sayfayı seçin ve komut dosyanızı ona ekleyin. Bir tür "bulunamadı" sayfası muhtemelen iyi olacaktır).
(4) Gizli iframe sayfasındaki komut dosyasının yalnızca (a) kümeye ihtiyacı vardır document.domain = "example.com";
ve (b) bu yapıldığında ana pencereyi bilgilendirir. Bundan sonra, ana pencere iframe penceresine ve tüm nesnelerine kısıtlama olmaksızın erişebilir! Dolayısıyla, minimal iframe sayfası şuna benzer:
<!doctype html>
<html>
<head>
<script>
document.domain = "example.com";
window.parent.iframeReady();
</script>
</head>
<body></body>
</html>
Bir userscript yazma, bu tür harici olarak erişilebilir fonksiyonlar eklemek istemeyebilirsiniz iframeReady()
adresinden Müşteri unsafeWindow
, bu nedenle bunun yerine özel bir olay kullanmak olabilir ana pencere userscript bildirmek için daha iyi bir yol:
window.parent.dispatchEvent(new CustomEvent("iframeReady"));
Ana sayfanızın penceresine özel "iframeReady" etkinliği için bir dinleyici ekleyerek tespit edersiniz.
(NOT: iframe'in etki alanı zaten example.com olsa bile document.domain = "example.com" ayarını yapmanız gerekir: document.domain'e bir değer atanması örtük olarak kaynağın bağlantı noktasını boş olarak ayarlar ve her iki bağlantı noktası da iframe için eşleşmelidir ve ebeveyninin aynı kökenli olduğu kabul edilmelidir. Buradaki nota bakın: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin )
(5) iframe hazır olduğunu kendi üst pencere bildirdi gizli kez ana penceresindeki komut sadece kullanabilirsiniz iframe.contentWindow.localStorage
, iframe.contentWindow.indexedDB
, iframe.contentWindow.BroadcastChannel
, iframe.contentWindow.SharedWorker
yerine window.localStorage
, window.indexedDB
vb ... ve tüm bu nesneler alanına dahil edilecektir seçilen https: // ornek.com menşei - böylece tüm sayfalarınız için aynı paylaşılan menşeye sahip olurlar!
Bu tekniğin en garip yanı, devam etmeden önce iframe'in yüklenmesini beklemeniz gerektiğidir. Dolayısıyla, örneğin DOMContentLoaded işleyicinizde localStorage'ı pervasızca kullanmaya başlayamazsınız. Ayrıca, gizli iframe'in doğru şekilde yüklenip yüklenemediğini tespit etmek için bazı hata işlemleri eklemek isteyebilirsiniz.
Açıkçası, sayfanızın ömrü boyunca gizli iframe'in kaldırılmadığından veya gezinilmediğinden de emin olmalısınız ... OTOH Bunun sonucunun ne olacağını bilmiyorum ama çok büyük olasılıkla kötü şeyler olurdu.
Ve, bir uyarı: ayar / değişen document.domain
edilebilir engellenmiş kullanılarak Feature-Policy
anlatıldığı gibi bu tekniğin kullanılabilir olacaktır ki bu durumda başlık.
Bununla birlikte, bu tekniğin engellenemeyen Feature-Policy
ve aynı zamanda tamamen ilgisiz alanların verileri, iletişimleri ve paylaşılan çalışanları (yani yalnızca ortak bir üst alan adının alt alanlarını değil) paylaşmasına izin veren önemli ölçüde daha karmaşık bir genellemesi vardır . @Mayank Jain cevabında bunu zaten açıkladı, yani:
Genel fikir, yukarıda olduğu gibi, erişim için doğru kaynağı sağlamak üzere gizli bir iframe oluşturmanızdır; ancak daha sonra iframe penceresinin özelliklerini doğrudan almak yerine, tüm işi yapmak için iframe içinde komut dosyasını kullanırsınız ve iframe ile ana pencereniz arasında yalnızca postMessage()
ve kullanarak iletişim kurarsınız addEventListener("message",...)
.
Bu işe yarar çünkü postMessage()
farklı menşeli pencereler arasında bile kullanılabilir. Ama aynı zamanda önemli ölçüde daha karmaşıktır, çünkü her şeyi sadece localStorage, IndexedDB, vb. API'leri doğrudan ana pencerenizin kodunda kullanmak yerine, iframe ile ana pencere arasında oluşturduğunuz bir tür mesajlaşma altyapısından geçirmeniz gerekir.