alt etki alanlarında localStorage kullanın


105

Çerezleri, onu destekleyebilen tarayıcılarda (IE hariç herkes) localStorage ile değiştiriyorum . Sorun site.com ve www . site.com kendi ayrı localStorage nesnelerini depolar. Www'nin bir alt alan adı olarak kabul edildiğine inanıyorum (bana sorarsanız aptalca bir karar). Bir kullanıcı aslen site.com'da bulunuyorsa ve www yazmaya karar verirse . site.com bir sonraki ziyaretinde tüm kişisel verilerine erişilemez olacaktır. Tüm "alt alan adları" nın ana etki alanı olarak aynı localStorage'ı paylaşmasını nasıl sağlayabilirim?


4
Firefox ve IE8, kalıcı verilerin kullanıcı tarafından belirlenen bir etki alanı altında saklanmasını destekler. Örneğin, FF'de globalStorage ['site.com'] yapabilirsiniz ve bu, www.site.com ve site.com için erişilebilir olacaktır. Hala bunu Chrome uygulamasında nasıl yapacağımı bulamadım.
JoJo

9
Birini veya ikincisini kullanmayı düşünün - www ile ziyaret eden tüm kullanıcıları yeniden yönlendirin. alt etki alanı olmayan etki alanına alt etki alanı veya tam tersi.
Elad Nava

1
Uzun zaman önce bir makale oluşturdum: Cross-Domain
LocalStorage

Yanıtlar:


97

Etki alanlarında bunu böyle kullanıyorum ...

  • Ebeveyn alanınızdan bir iframe kullanın - parent.com deyin
  • Ardından her bir child.com etki alanında, parent.com iframe'inize bir postMessage göndermeniz yeterlidir.
  • Tüm yapmanız gereken, parent.com iframe ile konuşmak için postMessage mesajlarınızı nasıl yorumlayacağınıza dair bir protokol kurmaktır.

Umut ediyorum bu yardım eder :)


2
Bu gerçek cevap, işaretli değil. Bunu kendim yaptım ama aynı zamanda postMessage ile uygun bir geri arama sarmalayıcı oluşturdum.
Jason Sebring

4
İşte bu yöntemi açıklayan bazı örnek kodlu güzel bir makale: jcubic.wordpress.com/2014/06/20/cross-domain-localstorage
Todd Price

4
Bunun yalnızca üçüncü taraf çerezleri devre dışı bırakılmadığında mümkün olduğunu unutmayın: stackoverflow.com/a/44097269/4311428
maxeh

6
Apple, 3. taraf verilerini engellemek için hem masaüstü hem de mobil cihazlarda Safari 7+ için varsayılanları güncelledi. Seçenek artık "Çerezleri ve diğer web sitesi verilerini engelle" olarak adlandırılıyor ve yerel depolama gibi artık tamamen etki alanı tarafından izole edilmiş olan şeyleri ifade ediyor. Bu yöntem Safari'de işe yaramayacak
Aranganathan

2
@Max @Aranganathan hala orijinal soru durumu için çalışıyor - site.com/ www.site.comalt
alanlar

43

İframe ve postMessage çözümünü yalnızca bu belirli sorun için kullanıyorsanız, verileri yalnızca alt etki alanı olmayan bir çerezde depolamanın daha az iş (hem kod açısından hem de hesaplama açısından) olacağını düşünüyorum ve zaten değilse localStorage on load, onu çerezden alın .

Artıları:

  • Ekstra iframe ve postMessage kurulumuna ihtiyaç duymaz.

Eksileri:

  • Verileri tüm alt alan adlarında (yalnızca www değil) kullanılabilir hale getirir, böylece tüm alt alan adlarına güvenmezseniz sizin için çalışmayabilir.
  • Verileri her istek üzerine sunucuya gönderir. Harika değil, ancak senaryonuza bağlı olarak, iframe / postMessage çözümünden daha az iş olabilir.
  • Bunu yapıyorsanız, neden çerezleri doğrudan kullanmıyorsunuz? Bağlamınıza bağlıdır.
  • Etki alanı için tüm çerezlerde toplam 4K maks. Çerez boyutu (Bunu yorumlarda işaret ettiği için Blake'e teşekkürler)

Yine de diğer yorumcularla aynı fikirdeyim, bu localStorage için belirlenebilir bir seçenek gibi görünüyor, bu yüzden geçici çözümlere gerek yok.


32
Con: 4k maksimum çerez boyutu
Blake Miller

18
Ayrıca, zor yoldan öğrendiğim gibi, 4k sınırı, her çerez için değil, tek bir alan için tüm çerezlerin boyutlarının toplamı içindir.
Blake Miller

diğer dezavantajlar: - çerezler büyük olasılıkla reklam engelleyicileri tarafından engellenecektir - çerezler, sunucu ve müşteri arasında küçük verileri paylaşmak için kullanılır, eğer sunucu çerezde sakladığınız verileri kullanmıyorsa bu bir yanlış kullanımdır
Enno

34

Hem tutarlılık hem de bunun gibi sorunlardan kaçınmak için site.com'u www.site.com'a yönlendirmenizi öneririm.

Ayrıca, her tarayıcının yerel depolamasını kullanabilen PersistJS gibi bir çapraz tarayıcı çözümü kullanmayı düşünün .


Böyle bir yönlendirme yapmak için sunuculara yönetici erişimim yok. Bu kitaplık, kalıcı verileri www ve www olmayanlar arasında paylaşmama izin veriyor mu? Biraz okuduktan sonra, neredeyse tüm tarayıcıların depolama mekanizmaları buna izin vermiyor gibi görünüyor. Çerez veya localStorage olursa olsun, bu problemle karşılaşacağız ...
JoJo

Evet, depolama normalde alt alan dahil olmak üzere alana bağlıdır. Bu yüzden yeniden yönlendirme önerdim. Yönetici erişimine ihtiyacınız yok, sadece belge kökünde bir .htaccess kuralı kullanın
Eran Galperin

1
@JoJo Yeniden yönlendirmenin birkaç yolu vardır, örneğin başlık göndererek Locationveya <meta>HTML etiketi aracılığıyla ve hatta JS yoluyla window.location.
Sony Santos

1
Bu sadece cevaptan kaçmaktır. Mayank'ın cevabını doğru görün.
Jason Sebring

1
+1 @avoiding, artı bu diğer durumlar için alakasız - burada olduğum gibi lang1.domain.com - lang2.domain.com
r --------- k

12

Ana alanda çerez olarak ayarlayın -

document.cookie = "key=value;domain=.mydomain.com"

ve ardından verileri herhangi bir ana etki alanından veya alt etki alanından alıp localStorage'da ayarlayın



3

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.domainonları 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();  // function defined & called on parent window
  </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.SharedWorkeryerine window.localStorage, window.indexedDBvb ... 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.domainedilebilir engellenmiş kullanılarak Feature-Policyanlatıldığı gibi bu tekniğin kullanılabilir olacaktır ki bu durumda başlık.


Bununla birlikte, bu tekniğin engellenemeyen Feature-Policyve 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.



0

Web sitem için bu şekilde çözdüm. Www içermeyen tüm sayfaları www.site.com'a yönlendirdim. Bu şekilde, her zaman www.site.com'un yerel deposunu alacaktır.

.Htacess'inize aşağıdakileri ekleyin (zaten yoksa bir tane oluşturun) kök dizine

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

7
Buna olumsuz oy vermeye çok meyilliyim, ancak OP'nin kullanım durumuna yardımcı olabileceği için yapmayacağım, ancak myapp.com ve developer.myapp.com ve support.myapp.com'da oturumları tutmak isteyen kişiler için bu yanıt iyi değil.
Don Omondi

hey @DonOmondi Önerdiğiniz şeylerin bağlantılarıyla bana yardım edebilirseniz çok sevinirim!
Ayush Baheti

3
OP "alt etki alanlarında localStorage kullan" sorusunu sordu, cevabınız "www'yi www olmayanlara yönlendir" çok farklı şeylerdir, ancak yalnızca ve yalnızca belirli alt etki alanı "www.abc.com" ise işe yarayabilir, buradaki bazı diğer yanıtlar daha pratik.
Don Omondi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.