如何检测用户是否通过链接到达网页,ctrl+r或ctrl+shift+r重新加载
How to detect whether user reached webpage by link, ctrl+r or ctrl+shift+r reloads
如何检测用户如何到达页面?链接,重新加载(清除缓存或不?)在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+r
或ctrl+shift+r
)的答案。
主要区别在于重载不会影响当前页面url,无论它被设置为什么。因此,可以利用这一点来检测是否发生了重新加载。一种跨浏览器且不依赖于javascript可能或不可能访问的特性的方法是:
- 页面加载后,添加特定的随机散列到url,例如
#uuid=AGHJHFG64675
- 使用
cookies
或local storage
(如果可用)保存相同的哈希 - 在页面加载时,查看cookie(或本地存储)是否具有哈希值,并且它与url哈希值(如果存在)匹配。
- 如果满足这些条件,您知道已重新加载,而不是外部访问。
方法的利弊:
- 不依赖于不可访问的请求信息或类似的
- 是跨浏览器的
- 不容易检测简单的从缓存加载与重载绕过缓存(仍在考虑这个)
- 用户可以在重新加载之前手动操作和更改url哈希值。这是无法检验的,但这真的重要吗?例如,用户有意绕过此过程(如测试)
- Url哈希值可能会因页面交互而改变(例如点击
href=#target
链接)。这是不处理的,但也很容易处理这种情况,通过在hashchange
上添加处理程序并在缺少 时重置哈希键
如果您只关心通过ctrl-r链接/重新加载,那么我建议查看文档元素上的键盘,如果按下ctrl+r,则在sessionStorage中保存时间戳。请注意,如果你使用键盘事件,那么它不会知道是否有人点击了浏览器上的重新加载按钮(你也不会知道他们是否重新映射了重新加载键组合等)。
如果你只关心链接/重载(无论如何),那么我建议setInterval每秒钟保存一个时间戳到sessionStorage。
无论哪种方式,在页面加载时根据当前时间和1检查时间戳。如果它存在,2。如果它是最近的(最近5秒?),那么假设它是重新加载。这可能是错的,但希望不会错得太多。
需要记住的事情包括一些浏览器(如Firefox或各种Chrome扩展)在需要之前会将选项卡卸载(但sessionStorage完好无缺)-因此时间戳将存在但很旧-这可能意味着浏览器刷新或重新启动,而不是重新加载选项卡。
如果选择键盘路线,不要忘记OSX与Windows/Linux和平板电脑等有不同的修改键,根本不要使用它们。
- 如何防止网页加载后自动启动功能
- 如何使用Node.js最有效地解析网页
- 刷新后保留对网页的更改
- AJAX不会在文件上传后重定向到网页-POST方法
- 使用谷歌网站翻译器自动翻译网页
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- 仅重新加载网页的一部分
- 每次提交表单时都会重新加载网页
- 打开网页后立即获取网页的活动javascript函数
- 链接两个网页或网络应用程序的最佳方式
- Android键盘不适用于包含Javascript的网页
- 网页上失败的javascript会导致所有其他脚本失败
- 在网页上显示当前股票报价
- HTML 5 和 3.js 代码不会在网页上显示任何内容
- 使用javascript替换网页上的文本
- 如何建立一个网页,检查我的路由器网络接口是否可以访问
- 如何使用javascript/jquery识别html网页上的ctrl +click
- 如何在网页中通过ctrl+f进行搜索时触发事件
- Ctrl + C复制网页文本-复制额外的数据到剪贴板
- 如何检测用户是否通过链接到达网页,ctrl+r或ctrl+shift+r重新加载