Estou substituindo cookies por localStorage em navegadores que podem suportá-lo (qualquer um, exceto o IE). O problema é site.com e www . site.com armazena seus próprios objetos localStorage separados. Eu acredito que www é considerado um subdomínio (uma decisão estúpida se você me perguntar). Se um usuário estava originalmente em site.com e decide digitar www . site.com em sua próxima visita, todos os seus dados pessoais estarão inacessíveis. Como faço para que todos os meus "subdomínios" compartilhem o mesmo localStorage do domínio principal?
95
Respostas:
É assim que eu o uso em vários domínios ...
Espero que ajude :)
fonte
site.com
/www.site.com
contanto que os subdomínios estejam no mesmo domínio paiSe você estiver usando a solução iframe e postMessage apenas para este problema específico, acho que pode ser menos trabalhoso (tanto em termos de código quanto de computação) apenas armazenar os dados em um cookie sem subdomínio e, se ainda não estiver em localStorage no carregamento, pegue-o do cookie .
Prós:
Contras:
Eu concordo com outros comentadores, porém, parece que deve ser uma opção especificável para localStorage, portanto, não são necessárias soluções alternativas.
fonte
Eu sugiro fazer o site.com redirecionar para www.site.com para consistência e para evitar problemas como este.
Além disso, considere o uso de uma solução para vários navegadores como PersistJS, que pode usar o armazenamento nativo de cada navegador.
fonte
Location
, ou através da<meta>
tag HTML, ou mesmo JS viawindow.location
.Definir como cookie no domínio principal -
e, em seguida, pegue os dados de qualquer domínio principal ou subdomínio e defina-os no localStorage
fonte
Estou usando xdLocalStorage, esta é uma biblioteca js leve que implementa a interface LocalStorage e oferece suporte ao armazenamento de domínio cruzado usando a comunicação de mensagem post iframe. (Suporte angularJS)
https://github.com/ofirdagan/cross-domain-local-storage
fonte
este tipo de solução causa muitos problemas como este. para consistência e considerações de SEO, redirecionar no domínio principal é a melhor solução.
faça o redirecionamento no nível do servidor
Como redirecionar www para não www com Nginx
https://www.digitalocean.com/community/tutorials/how-to-redirect-www-to-non-www-with-nginx-on-centos-7
ou qualquer outro nível como a rota 53 se estiver usando
fonte
Foi assim que resolvi para o meu site. Redirecionei todas as páginas sem www para www.site.com. Dessa forma, sempre levará o armazenamento local de www.site.com
Adicione o seguinte ao seu .htacess (crie um se ainda não tiver) no diretório raiz
fonte
É assim:
Para compartilhar entre subdomínios de um determinado superdomínio (por exemplo, exemplo.com), existe uma técnica que você pode usar nessa situação. Pode ser aplicado para
localStorage
,IndexedDB
,SharedWorker
,BroadcastChannel
, etc, todos os quais oferecem funcionalidade compartilhada entre as páginas de mesma origem, mas por alguma razão não respeitam qualquer modificaçãodocument.domain
que iria deixá-los usar o superdomínio como sua origem diretamente.(1) Escolha um domínio "principal" para os dados pertencerem: ou seja, https://example.com ou https://www.example.com manterá seus dados localStorage. Digamos que você escolha https://example.com .
(2) Use localStorage normalmente para as páginas do domínio escolhido.
(3) Em todas as páginas https://www.example.com (o outro domínio), use javascript para definir
document.domain = "example.com";
. Em seguida, crie também um oculto<iframe>
e navegue até alguma página no domínio https://example.com escolhido ( não importa qual , contanto que você possa inserir um pequeno trecho de javascript nela. Se você ' Ao re-criar o site, basta fazer uma página vazia especificamente para este propósito. Se você estiver escrevendo uma extensão ou um script de usuário no estilo Greasemonkey e, portanto, não tiver nenhum controle sobre as páginas no example.com servidor de página , basta escolher a página mais leve que puder encontrar e inserir seu script nela. uma página "não encontrada" provavelmente seria adequada).(4) O script na página oculta do iframe precisa apenas (a) definir
document.domain = "example.com";
e (b) notificar a janela pai quando isso for feito. Depois disso, a janela pai pode acessar a janela iframe e todos os seus objetos sem restrição! Portanto, a página iframe mínima é algo como:Se estiver escrevendo um userscript, você pode não querer adicionar funções acessíveis externamente, como o
iframeReady()
seuunsafeWindow
, então, em vez disso, a melhor maneira de notificar o userscript da janela principal pode ser usar um evento personalizado:Que você detectaria adicionando um listener para o evento "iframeReady" personalizado à janela da página principal.
(Na verdade, eu escrevi esta resposta para o caso geral em que o domínio escolhido não é necessariamente o superdomínio example.com . Mas, como já está aqui , provavelmente nem precisamos definir
document.domain
no iframe - então a única coisa necessário é que a janela principal seja notificada quando o iframe estiver pronto para ser acessado).(5) Uma vez que o escondido iframe informou sua janela pai que ele está pronto, roteiro na janela pai pode apenas usar
iframe.contentWindow.localStorage
,iframe.contentWindow.indexedDB
,iframe.contentWindow.BroadcastChannel
,iframe.contentWindow.SharedWorker
em vez dewindow.localStorage
,window.indexedDB
, etc. ... e todos estes objetos serão escopo para o escolhido https: // origem de example.com - então eles terão a mesma origem compartilhada para todas as suas páginas!A parte mais complicada dessa técnica é que você precisa aguardar o carregamento do iframe antes de prosseguir. Portanto, você não pode simplesmente começar a usar localStorage em seu manipulador DOMContentLoaded, por exemplo. Além disso, você pode querer adicionar algum tratamento de erro para detectar se o iframe oculto falha ao carregar corretamente.
Obviamente, você também deve certificar-se de que o iframe oculto não seja removido ou navegado durante o tempo de vida da sua página ... OTOH Não sei qual seria o resultado disso, mas muito provavelmente coisas ruins aconteceriam.
E, uma advertência: a configuração / alteração
document.domain
pode ser bloqueada usando oFeature-Policy
cabeçalho, caso em que esta técnica não será utilizável conforme descrito.No entanto, há uma generalização significativamente mais complicada dessa técnica, que não pode ser bloqueada por
Feature-Policy
, e que também permite que domínios totalmente não relacionados compartilhem dados, comunicações e trabalhos compartilhados (ou seja, não apenas subdomínios de um superdomínio comum). @Mayank Jain já o descreveu em sua resposta, a saber:A ideia geral é que, assim como acima, você crie um iframe oculto para fornecer a origem correta para o acesso; mas em vez de apenas pegar as propriedades da janela do iframe diretamente, você usa o script dentro do iframe para fazer todo o trabalho e se comunica entre o iframe e sua janela principal usando apenas
postMessage()
eaddEventListener("message",...)
.Isso funciona porque
postMessage()
pode ser usado mesmo entre janelas de origens diferentes. Mas também é significativamente mais complicado porque você precisa passar tudo por algum tipo de infraestrutura de mensagens criada entre o iframe e a janela principal, em vez de apenas usar as APIs localStorage, IndexedDB etc. diretamente no código da janela principal.fonte