Как определить, достиг ли пользователь веб-страницы по ссылке, ctrl + r или ctrl + shift + r reloads
Как определить, как пользователь достиг страницы? Ссылка, перезагрузка (с прозрачным кэшем или нет?) В хроме?
Я использую angular. Мой заголовок ответа содержит:
Cache-Control:max-age=3600
Last-Modified:Tue, 19 May 2015 06:19:02 GMT
1) Это ведет себя так, как ожидалось, когда я перезагружаю (ctrl + r), запрос для всех файлов содержит
Cache-Control:max-age=0
If-Modified-Since:Tue, 19 May 2015 06:19:02 GMT
Если файл не изменен, я получаю
Status Code:304 Not Modified
2) Если я перезагружаюсь с помощью (ctrl + shift + r) или добираюсь до веб-сайта в первый раз, я получаю
Cache-Control:no-cache
Pragma:no-cache
и файл будет загружен заново.
3) Если я перейду на веб-страницу по ссылке, она загрузит файлы из кеша, если они были выбраны и еще 3600 секунд до этого.
Status Code:200 OK (from cache)
EXCEPT html файлы, которые я загружаю с помощью ng-include src= "''"
Они всегда извлекаются из кеша. Я должен удалить кеш всего браузера, чтобы они были извлечены заново. Даже ctrl + shift + r не работает. Отключить кеш в инструментах разработчика, так как в нем останавливается кеширование.
Итак, я добавил кое-что в конфигурацию приложения angular.
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
После этого только новые html-шаблоны всегда извлекаются заново. Я заметил, что хром также использует ниже двух заголовков запросов
Cache-Control: 'no-cache'
Pragma: 'no-cache'
и такие файлы подчиняются правилам кэша, кроме шаблонов .html. Почему?
Если я изменил приведенные выше строки на
$httpProvider.defaults.headers.get['Cache-Control'] = 'max-age=x';
то он работает так, как ожидалось, выборка из кэша до истечения срока действия, а затем проверить, не изменился ли он на сервере из кеша. Но таким образом он не будет подчиняться перезагрузке ctrl + r, где chrome отправляет
Cache-Control:max-age=0
Итак, как я могу определить, как пользователь достиг веб-страницы в chrome/firefox/etc.?
Другая альтернатива заключается в том, чтобы сделать angular $http всегда использовать те же заголовки, что и хром, когда он извлекает файл? правильно? Это всегда имитирует HTTP-запросы браузера
Как проверяется проверка ошибок document.referrer
?
Ответы
Ответ 1
В принципе, доступ к заголовкам запросов, порожденных браузером, невозможен с точки зрения JavaScripts. Браузер просто не позволяет вам видеть эти запросы.
Для запросов XHR, например, те, что Angular использует для извлечения своих шаблонов, нажали ли Ctrl + R, Ctrl + Shift + R или просто нажали ссылку, не имеет никакого значения, поскольку это действует только на исходный ресурс (документ ) и все файлы, напрямую связанные с ними.
Реферрером на самом деле не на что можно положиться, поскольку некоторые браузеры поддерживают реферер при обновлении, а некоторые нет, поэтому вы не можете видеть разницу между перезагрузкой и щелчком ссылки. Также, если вы обрабатываете пустой реферер как перезагрузку без кэша, люди, приходящие на вашу страницу, введя сам URL-адрес, никогда не смогут получить кешированную версию.
Единственный способ увидеть, какие заголовки отправляются браузером, и, таким образом, настройка метода кэширования будет заключаться в том, чтобы иметь на стороне сервера script, например, в PHP, чтобы проверить их и записать правильную функцию кэширования в ответ либо в скрытое поле формы или файл cookie или сгенерированный файл JavaScript. Если вы используете этот параметр, вы захотите убедиться, что PHP скрипт, который проверяет заголовки кеширования, запрашивается самим браузером, а не через XHR.
И снова, позволяя вашему первоначальному методу загрузки влиять на запросы позже, сделанные через AJAX, возможно, даже не будут такими, какие вы хотите. Если это проблема, с которой вы сталкиваетесь во время разработки, например, лучше всего просто открыть консоль разработчика, отстыковать ее из окна и сохранить в фоновом режиме.
Если ваши пользователи видят устаревшие шаблоны на производстве, вам лучше использовать сервер для настройки кэширования для файлов HTML, а также уменьшить время кеша и использовать настройки ETag в соответствии с вашими потребностями. Современные браузеры всегда будут уважать настройки, возвращаемые вашим сервером при определении того, как кэшировать их запросы, и так будет Angular при запросе шаблонов.
Наконец, если вы видите устаревшие шаблоны во время выполнения приложения, это потому, что Angular будет хранить шаблон в памяти после его начальной загрузки и никогда не запрашивать его снова, если вы специально не попросите его через шаблон $templateCache.
Ответ 2
Здесь используется метод "hack-ish" для предотвращения кеширования 100% - для добавления параметра строки запроса в URL-адрес. Может быть
<div ng-include src="'./myfile.html?random_number=123456'"></div>
(Иногда даже добавление одного и того же параметра строки запроса предотвращает кеширование браузера ресурсом)
Я не большой специалист по AngularJS, но я думаю, что вы можете использовать выражения Angular в атрибуте "src"
, что-то вроде этого:
$scope.myRandomNumber = new Date().getTime(); //milliseconds since 1970
Затем в вашем HTML:
<div ng-include src="'./myfile.html?random_number=' + myRandomNumber"></div>
Ответ 3
Я не уверен, но я не думаю, что вы на правильном пути, чтобы решить эту проблему. вы должны сосредоточиться на механизмах кэширования. обнаружение ключей или схема загрузки страниц и изменение заголовков кеша в соответствии с этим, кажется, слишком много проблем, не стоит проблемы.
но для записи. Я думал, что вы можете использовать некоторую клавиатурную библиотеку для angular и localstorage в браузере. поэтому вы можете определить, какие клавиши были нажаты, и записать эту информацию в localstorage.
на странице проверки открытого хранилища. если это
empty → это может быть ссылка или первая страница открыта
not empty → все, что вы написали в localstorage, нажали последние клавиши времени
и очистить хранилище.
проверьте эти
https://github.com/chieffancypants/angular-hotkeys/
https://github.com/grevory/angular-local-storage
Ответ 4
Вопрос включает две части, правильное использование кеширования и способы обнаружения, если пользователь приземлился на веб-странице извне или обновил страницу. Это не обязательно связано, здесь будет дан ответ на обнаружение посещений веб-сайтов и перезагрузки (например, ctrl+r
или ctrl+shift+r
).
Основное отличие заключается в том, что reload не повлияет на текущий URL-адрес страницы, на который он был установлен. Таким образом, это может быть использовано для обнаружения повторной загрузки. Способ сделать этот кросс-браузер и не полагаться на функции, которые могут быть доступны или недоступны из javascript, таков:
- После загрузки страницы добавьте определенный рандомизированный хэш к URL, например
#uuid=AGHJHFG64675
- Сохраните тот же хеш с помощью
cookies
или local storage
(если есть)
- На загрузке страницы посмотрите, имеет ли файл cookie (или локальное хранилище) хэш и что он соответствует хешу URL (если он есть).
- Если эти условия выполнены, вы знаете, что была сделана перезагрузка, а не внешний визит.
Плюсы и минусы подхода:
- Не полагается на недоступную информацию запроса или аналогичную
- Это кросс-браузер
- Нелегко обнаружить простую перезагрузку из кеша и перезагрузить обход кеша (все еще думая об этом)
- Пользователь может вручную манипулировать и изменять хэш URL-адресов, прежде чем выполнять перезагрузку. Это невозможно проверить, но действительно ли это имеет значение? Например, пользователь хочет обойти эту процедуру специально (например, тестирование).
- Хеш Url может измениться по другим причинам из-за взаимодействия с страницей (например, нажмите ссылку с
href=#target
). Это не обрабатывается, но в этом случае легко справиться, добавив обработчик на hashchange
и reset хеш-ключ, если он отсутствует.
Ответ 5
Если вы только занимаетесь ссылкой/перезагрузкой через ctrl-r, я бы предложил посмотреть клавиатуру на элементе документа, а если нажать Ctrl + R, сохраните временную метку в sessionStorage. Обратите внимание: если вы используете событие с клавиатурой, то он не будет знать, нажал ли кто-нибудь кнопку перезагрузки в браузере (и вы также не узнаете, обновили ли они комбинацию перезагрузки и т.д.).
Если вы интересуетесь только ссылкой/перезагрузкой (независимо от того, как), я бы предложил setInterval сохранять временную метку для sessionStorage каждую секунду.
В любом случае, при загрузке страницы отметьте отметку времени с текущим временем и 1. если она существует и 2. если она была последней (последние 5 секунд, может быть?), тогда предположите, что она перезагружается. Возможно, это неправильно, но, надеюсь, не так много.
Следует учитывать тот факт, что некоторые браузеры (например, Firefox или различные расширения Chrome) оставляют вкладки разгруженными (но с неповрежденными sessionStorage) до тех пор, пока они не понадобятся - так что временная метка будет существовать, но быть старой - что, вероятно, будет означать либо обновить или перезагрузить браузер, в отличие от перезагрузки табуляции.
Если вы идете по маршруту клавиатуры, не забывайте, что OSX имеет разные ключи-модификаторы для Windows/Linux, а планшеты и т.д. вообще не используют их.