如何检测用户是否通过链接到达网页,ctrl+r或ctrl+shift+r重新加载

How to detect whether user reached webpage by link, ctrl+r or ctrl+shift+r reloads

本文关键字:ctrl+r 网页 ctrl+shift+r 新加载 加载 链接 检测 何检测 用户 是否      更新时间:2023-09-26

如何检测用户如何到达页面?链接,重新加载(清除缓存或不?)在chrome?

我用的是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)

除了我用ng-include加载的html文件

总是从缓存中获取。我必须删除整个浏览器的缓存,以便重新获取它们。甚至ctrl+shift+r都不起作用。在开发人员工具中禁用缓存就像停止缓存一样。

所以我在我的angular应用配置中添加了一些东西。

$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';

在此之后,只有html模板总是被新获取。我注意到chrome还使用以下两个请求头

Cache-Control: 'no-cache'
Pragma: 'no-cache'

等文件遵循缓存规则,除了.html模板。为什么?

如果我把上面的行改为

$httpProvider.defaults.headers.get['Cache-Control'] = 'max-age=x';

然后按预期工作,从缓存中读取直到过期,然后检查是否没有从缓存中修改服务器。但是这样它就不会服从ctrl+r reload, chrome发送

Cache-Control:max-age=0

那么我如何检测用户如何在chrome/firefox/等中访问网页?

另一种选择是让angular $http总是使用相同的头像chrome当它获取文件?对吧?这总是模仿浏览器的http调用

检查document.referrer有多安全?

基本上,从javascript的角度来看,访问浏览器生成的请求的标头是不可能的。浏览器根本不允许您看到这些请求。

对于XHR请求,比如Angular用来获取模板的请求,无论你按Ctrl+R、Ctrl+Shift+R还是只是按一个链接都没有区别,因为它只作用于初始资源(文档)和所有从那里直接链接的文件。

referrer并不是你真正可以依赖的东西,因为有些浏览器保持referrer刷新,有些浏览器没有,所以你看不出重载和点击链接之间的区别。此外,如果您将空引用视为无缓存的重新加载,那么通过输入URL来访问您的页面的人将永远无法获得缓存版本。

查看浏览器发送的头,从而调整缓存方法的唯一方法是让一些服务器端脚本(例如PHP)检查它们并将正确的缓存选项写入隐藏表单字段或cookie或生成JavaScript文件的响应中。如果使用此选项,则需要确保检查缓存头的PHP脚本是由浏览器本身请求的,而不是通过XHR请求的。

然后,允许您的初始加载方法影响稍后通过AJAX发出的请求甚至可能不是您想要的。例如,如果这是你在开发过程中遇到的问题,最好保持开发者控制台打开,将其从窗口中移除,并将其保留在后台。

如果您的用户在生产中看到陈旧的模板,您最好使用您的服务器为HTML文件设置缓存,并根据您的需要减少缓存时间并使用ETag设置。现代浏览器在决定如何缓存请求时,总是会尊重服务器返回的设置,Angular在请求模板时也是如此。

最后,如果你在应用运行时看到陈旧的模板,那是因为Angular会在初始加载后将模板保存在内存中,并且永远不会再次请求它,除非你通过$templateCache特别请求它。

有一种防止100%缓存的暴力破解方法——向URL添加查询字符串参数。可以在

<div ng-include src="'./myfile.html?random_number=123456'"></div>

(有时甚至添加相同的查询字符串参数也会阻止浏览器缓存资源)

我不是AngularJS的专家,但我认为你可以在"src"属性中使用Angular的"表达式",像这样:

$scope.myRandomNumber = new Date().getTime(); //milliseconds since 1970

然后在HTML中:

<div ng-include src="'./myfile.html?random_number=' + myRandomNumber"></div>

我不确定,但我认为你解决这个问题的方法不对。您应该关注缓存机制。检测键或页面加载方案并根据此修改缓存头似乎太麻烦了,不值得这样做。

但郑重声明。我在想你可以在浏览器上为angular和localstorage使用一些按键库。因此,您可以识别按下了哪些键并将该信息写入localstorage。

页打开检查存储。如果是

empty ->可能是链接或第一页打开

not empty ->上次按下键时写的内容

和清空存储

检查这些

https://github.com/chieffancypants/angular-hotkeys/

https://github.com/grevory/angular-local-storage

这个问题涉及两个部分,正确使用缓存和检测用户是否从外部登陆网页或刷新页面的方法。这些不一定是相关的,这里将给出关于web访问检测与重新加载(例如ctrl+rctrl+shift+r)的答案。

主要区别在于重载不会影响当前页面url,无论它被设置为什么。因此,可以利用这一点来检测是否发生了重新加载。一种跨浏览器且不依赖于javascript可能或不可能访问的特性的方法是:

  1. 页面加载后,添加特定的随机散列到url,例如#uuid=AGHJHFG64675
  2. 使用cookieslocal storage(如果可用)保存相同的哈希
  3. 在页面加载时,查看cookie(或本地存储)是否具有哈希值,并且它与url哈希值(如果存在)匹配。
  4. 如果满足这些条件,您知道已重新加载,而不是外部访问。

方法的利弊:

  1. 不依赖于不可访问的请求信息或类似的
  2. 是跨浏览器的
  3. 不容易检测简单的从缓存加载与重载绕过缓存(仍在考虑这个)
  4. 用户可以在重新加载之前手动操作和更改url哈希值。这是无法检验的,但这真的重要吗?例如,用户有意绕过此过程(如测试)
  5. Url哈希值可能会因页面交互而改变(例如点击href=#target链接)。这是不处理的,但也很容易处理这种情况,通过在hashchange上添加处理程序并在缺少
  6. 时重置哈希键

如果您只关心通过ctrl-r链接/重新加载,那么我建议查看文档元素上的键盘,如果按下ctrl+r,则在sessionStorage中保存时间戳。请注意,如果你使用键盘事件,那么它不会知道是否有人点击了浏览器上的重新加载按钮(你也不会知道他们是否重新映射了重新加载键组合等)。

如果你只关心链接/重载(无论如何),那么我建议setInterval每秒钟保存一个时间戳到sessionStorage。

无论哪种方式,在页面加载时根据当前时间和1检查时间戳。如果它存在,2。如果它是最近的(最近5秒?),那么假设它是重新加载。这可能是错的,但希望不会错得太多。

需要记住的事情包括一些浏览器(如Firefox或各种Chrome扩展)在需要之前会将选项卡卸载(但sessionStorage完好无缺)-因此时间戳将存在但很旧-这可能意味着浏览器刷新或重新启动,而不是重新加载选项卡。

如果选择键盘路线,不要忘记OSX与Windows/Linux和平板电脑等有不同的修改键,根本不要使用它们。