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

时间:2015-05-19 07:15:21

标签: javascript html angularjs http caching

如何检测用户访问网页的方式?在Chrome中链接,重新加载(clear-cached或not?)?

我正在使用棱角分明。我的回复标题包含:

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文件src =“''”

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

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

$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 重新加载chrome发送

Cache-Control:max-age=0

那么如何检测用户如何通过chrome / firefox /等到达网页?

另一个替代方法是使角$ http在获取文件时始终使用与chrome相同的标题?对?这总是模仿浏览器http调用

检查document.referrer是多么万无一失?

5 个答案:

答案 0 :(得分:3)

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

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

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

查看浏览器发送哪些标头,从而调整缓存方法的唯一方法是在PHP中使用某些服务器端脚本检查它们并以隐藏形式将正确的缓存选项写入响应字段或cookie或生成JavaScript文件。如果您正在使用此选项,则需要确保浏览器本身而非XHR请求检查缓存标头的PHP脚本。

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

如果您的用户在生产中看到过时的模板,您最好使用服务器设置HTML文件的缓存,并根据需要减少缓存时间并使用ETag设置。现代浏览器在确定如何缓存请求时将始终遵循服务器返回的设置,因此Angular在请求模板时也会如此。

最后,如果您在应用程序运行时期间看到过时的模板,那是因为Angular会在其初始加载后将模板保留在内存中,并且除非您通过$ templateCache明确要求它,否则永远不会再请求它。

答案 1 :(得分:1)

有一个暴力行为&#34; hack-ish&#34;防止缓存100%的方法 - 向URL添加查询字符串参数。可能是

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

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

我不是AngularJS的大专家,但我认为你可以使用Angular&#34;表达式&#34;在"src"属性中,如下所示:

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

然后在你的HTML中:

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

答案 2 :(得分:0)

我不确定,但我认为你没有找到解决这个问题的正确方法。你应该专注于缓存机制。检测密钥或页面加载方案并根据此修改缓存标头似乎太麻烦,不值得这个问题。

但是为了记录。我以为你可以在浏览器上使用一些按键库来进行角度和localstorage。这样你就可以确定按下哪些键并将这些信息写入localstorage。

页面打开检查存储。如果是

空 - &gt;它可能是链接或首页打开

不为空 - &gt;你上次按下键时写到localstorage的任何内容

并清除存储空间。

检查这些

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

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

答案 3 :(得分:0)

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

主要区别在于重新加载不会影响当前页面网址,无论此设置如何。因此可以利用这个来检测重载是否已经发生。一种跨浏览器的方式,而不依赖于可能从javascript访问或不可访问的功能,这是:

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

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

答案 4 :(得分:0)

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

如果您只关心链接/重新加载(无论如何),那么我建议使用setInterval每秒为sessionStorage保存一个时间戳。

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

要记住的事项包括以下事实:某些浏览器(例如Firefox或各种Chrome扩展程序)会在需要之前将标签卸载(但是sessionStorage完好无损) - 因此时间戳将存在但很旧 - 这可能意味着要么浏览器刷新或重新启动而不是选项卡重新加载。

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