Я заменяю файлы cookie на localStorage в браузерах, которые могут его поддерживать (кто угодно, кроме IE). Проблема в site.com и www . site.com хранят свои собственные отдельные объекты localStorage. Я считаю, что www считается субдоменом (глупое решение, если вы спросите меня). Если пользователь изначально был на site.com и решил ввести www . site.com при ее следующем посещении все ее личные данные будут недоступны. Как мне сделать так, чтобы все мои «поддомены» использовали тот же localStorage, что и основной домен?
102
Ответы:
Вот как я использую его в разных доменах ...
Я надеюсь, что это помогает :)
источник
site.com
/www.site.com
пока субдомены находятся в одном родительском доменеЕсли вы используете решение iframe и postMessage только для этой конкретной проблемы, я думаю, что может быть меньше работы (как с точки зрения кода, так и с точки зрения вычислений), чтобы просто сохранить данные в файле cookie без поддомена, и, если он еще не в localStorage при загрузке возьмите его из файла cookie .
Плюсы:
Минусы:
Я согласен с другими комментаторами, похоже, что это должна быть конкретная опция для localStorage, поэтому обходные пути не требуются.
источник
Я предлагаю сделать переадресацию site.com на www.site.com как для единообразия, так и для предотвращения подобных проблем.
Также рассмотрите возможность использования кросс-браузерного решения, такого как PersistJS, которое может использовать каждое собственное хранилище браузера.
источник
Location
, через<meta>
тег HTML или даже через JSwindow.location
.Установить cookie в основном домене -
document.cookie = "key=value;domain=.mydomain.com"
а затем возьмите данные из любого основного домена или поддомена и установите их в localStorage
источник
Я использую xdLocalStorage, это легкая js-библиотека, которая реализует интерфейс LocalStorage и поддерживает междоменное хранилище с помощью сообщений сообщений iframe post. (Поддержка angularJS)
https://github.com/ofirdagan/cross-domain-local-storage
источник
Вот как:
[ Обновление за ноябрь 2020 г .: это решение зависит от возможности установить
document.domain
. К сожалению, такая возможность устарела. ]Для обмена между поддоменами данного супердомена (например, example.com) есть метод, который вы можете использовать в этой ситуации. Он может быть применен к
localStorage
,IndexedDB
,SharedWorker
,BroadcastChannel
и т.д., все из которых имеют общую функциональность между же происхождения страниц, но по какой - то причине не соблюдают никаких изменений,document.domain
которые позволили бы им использовать супердомена как их происхождение непосредственно.(1) Выберите один «основной» домен, к которому будут принадлежать данные: например, https://example.com или https://www.example.com. которому будут будет содержать ваши данные localStorage. Допустим, вы выбрали https://example.com .
(2) Обычно используйте localStorage для страниц выбранного домена.
(3) На всех страницах https://www.example.com ( другой домен) используйте javascript для установки
document.domain = "example.com";
. Затем также создайте скрытый<iframe>
и перейдите на какую-либо страницу в выбранном домене https://example.com ( неважно, на какой странице , если вы можете вставить туда очень маленький фрагмент javascript. Если вы при повторном создании сайта просто создайте пустую страницу специально для этой цели. Если вы пишете расширение или пользовательский скрипт в стиле Greasemonkey и не имеете никакого контроля над страницами на example.comserver, просто выберите самую легкую из возможных страниц и вставьте на нее свой скрипт. Возможно, подойдет какая-то страница "не найдена").(4) Скрипт на скрытой странице iframe нужно только (а) установить
document.domain = "example.com";
и (б) уведомить родительское окно, когда это будет сделано. После этого родительское окно может получить доступ к окну iframe и всем его объектам без ограничений! Итак, минимальная страница iframe выглядит примерно так:<!doctype html> <html> <head> <script> document.domain = "example.com"; window.parent.iframeReady(); // function defined & called on parent window </script> </head> <body></body> </html>
При написании пользовательского скрипта вы, возможно, не захотите добавлять функции, доступные извне, такие как
iframeReady()
вашunsafeWindow
, поэтому вместо этого лучшим способом уведомить пользовательский скрипт главного окна может быть использование настраиваемого события:window.parent.dispatchEvent(new CustomEvent("iframeReady"));
Это можно обнаружить, добавив слушателя для пользовательского события iframeReady в окно главной страницы.
(ПРИМЕЧАНИЕ: вам необходимо установить document.domain = "example.com", даже если домен iframe уже example.com : присвоение значения document.domain неявно устанавливает для порта источника значение null, и оба порта должны совпадать для iframe. и его родительский элемент должен рассматриваться как тот же источник. См. примечание здесь: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin )
(5) После того , как скрытый IFrame сообщил его родительское окно , что он готов, сценарий в родительском окне можно просто использовать
iframe.contentWindow.localStorage
,iframe.contentWindow.indexedDB
,iframe.contentWindow.BroadcastChannel
,iframe.contentWindow.SharedWorker
вместо тогоwindow.localStorage
,window.indexedDB
и т.д. ... и все эти объекты будут область видимости выбранной https: // example.com origin - так что у них будет одно и то же общее происхождение для всех ваших страниц!Самая неудобная часть этого метода заключается в том, что вам нужно дождаться загрузки iframe, прежде чем продолжить. Таким образом, вы не можете просто беспечно начать использовать localStorage в своем обработчике DOMContentLoaded, например. Также вы можете добавить некоторую обработку ошибок, чтобы определить, не загружается ли скрытый iframe правильно.
Очевидно, вы также должны убедиться, что скрытый iframe не удаляется или не перемещается в течение всего срока службы вашей страницы ... OTOH Я не знаю, каков будет результат, но очень вероятно, что произойдет что-то плохое.
И предостережение: настройку / изменение
document.domain
можно заблокировать с помощьюFeature-Policy
заголовка, и в этом случае этот метод нельзя будет использовать, как описано.Однако существует значительно более сложное обобщение этого метода, которое не может быть заблокировано
Feature-Policy
, и которое также позволяет совершенно несвязанным доменам обмениваться данными, коммуникациями и совместно используемыми рабочими (т.е. не только поддоменами из общего супердомена). @Mayank Jain уже описал это в своем ответе, а именно:Общая идея заключается в том, что, как и выше, вы создаете скрытый iframe, чтобы обеспечить правильное происхождение для доступа; но вместо того, чтобы напрямую захватывать свойства окна iframe, вы используете сценарий внутри iframe для выполнения всей работы, и вы общаетесь между iframe и вашим главным окном, используя только
postMessage()
иaddEventListener("message",...)
.Это работает, потому что
postMessage()
может использоваться даже между окнами разного происхождения. Но это также значительно сложнее, потому что вам нужно передать все через какую-то инфраструктуру обмена сообщениями, которую вы создаете между iframe и главным окном, а не просто использовать API localStorage, IndexedDB и т. Д. Непосредственно в коде вашего главного окна.источник
такое решение вызывает множество подобных проблем. по соображениям согласованности и SEO перенаправление на основной домен - лучшее решение.
сделать это перенаправление на уровне сервера
Как перенаправить www на не-www с помощью Nginx
https://www.digitalocean.com/community/tutorials/how-to-redirect-www-to-non-www-with-nginx-on-centos-7
или любой другой уровень, например маршрут 53, если вы используете
источник
Вот как я решил это для своего сайта. Я перенаправил все страницы без www на www.site.com. Таким образом, всегда будет использоваться локальное хранилище www.site.com.
Добавьте следующее в свой .htacess (создайте его, если у вас его еще нет) в корневом каталоге
RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
источник