强制浏览器使用本地缓存,不要和服务器通信如何做到
答案:2 悬赏:50
解决时间 2021-01-04 22:50
- 提问者网友:嘚啵嘚啵
- 2021-01-04 06:34
强制浏览器使用本地缓存,不要和服务器通信如何做到
最佳答案
- 二级知识专家网友:duile
- 2021-01-04 07:53
资源在浏览器端的本地缓存可以通过Expires和Last-Modified返回头信息进行有效控制。
1)Expires告诉浏览器在该指定过期时间前再次访问同一URL时,直接从本地缓存读取,无需再向服务器发起http请求;
优点是:浏览器直接读取缓存信息无需发起http请求。
缺点是:当用户按F5或Ctl+F5刷新页面时浏览器会再次发起http请求。
2)当服务器返回设置了Last-Modified头,下次发起同一URL的请求时,请求头会自动包含If-Modified-Since头信息,服务器对静态内容会根据该信息跟文件的最后修改时间做比较,如果最后修改时间不大于If-Modified-Since头信息,则返回304。告诉浏览器请求内容未更新可直接使用本地缓存。(注意:只对静态内容有效,如js/css/image/html等,不包括动态内容,如JSP)
优点:无论用户行为如何都有效;
缺点:仍需向服务器发起一次http请求;
对IE来说,本地缓存一般是在这个位置:
C:\Documents and Settings\\Local Settings\Temporary Internet Files
下面我用一个图片缓存的例子来说明,如何结合这两个参数来有效利用本地缓存,例子中图片存储在一个分布式文件系统,需要通过特定API才能获取而非直接存储在服务器上静态文件:
response.setContentType("image/jpeg");
response.setHeader("Cache-Control", "public");
response.setHeader("Pragma", "Pragma");
//本地缓存10分钟过期
response.setDateHeader("Expires", System.currentTimeMillis()+10*60*1000);
//设置Last-Modified
response.setDateHeader("Last-Modified", System.currentTimeMillis());
//判断请求中的If-Modified-Since头信息
if(request.getHeader("If-Modified-Since") == null){
//首次访问或者用户按Ctl+F5,从文件系统重新读取图片
//...get file from dfs
} else {
//返回304,告诉浏览器使用本地缓存
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
这种做法的一个缺点就是假设用户在第一次图片下载过程中网络有异常,下载的照片不完整,那用户在刷新,甚至重启浏览器后还是无法获取完整的照片,可能会影响极小部分用户的体验,虽然可以通过ctl+f5忽略Last-Modified或者清空缓存重新下载照片但是大部分普通用户可能不了解这些技巧。
1)Expires告诉浏览器在该指定过期时间前再次访问同一URL时,直接从本地缓存读取,无需再向服务器发起http请求;
优点是:浏览器直接读取缓存信息无需发起http请求。
缺点是:当用户按F5或Ctl+F5刷新页面时浏览器会再次发起http请求。
2)当服务器返回设置了Last-Modified头,下次发起同一URL的请求时,请求头会自动包含If-Modified-Since头信息,服务器对静态内容会根据该信息跟文件的最后修改时间做比较,如果最后修改时间不大于If-Modified-Since头信息,则返回304。告诉浏览器请求内容未更新可直接使用本地缓存。(注意:只对静态内容有效,如js/css/image/html等,不包括动态内容,如JSP)
优点:无论用户行为如何都有效;
缺点:仍需向服务器发起一次http请求;
对IE来说,本地缓存一般是在这个位置:
C:\Documents and Settings\
下面我用一个图片缓存的例子来说明,如何结合这两个参数来有效利用本地缓存,例子中图片存储在一个分布式文件系统,需要通过特定API才能获取而非直接存储在服务器上静态文件:
response.setContentType("image/jpeg");
response.setHeader("Cache-Control", "public");
response.setHeader("Pragma", "Pragma");
//本地缓存10分钟过期
response.setDateHeader("Expires", System.currentTimeMillis()+10*60*1000);
//设置Last-Modified
response.setDateHeader("Last-Modified", System.currentTimeMillis());
//判断请求中的If-Modified-Since头信息
if(request.getHeader("If-Modified-Since") == null){
//首次访问或者用户按Ctl+F5,从文件系统重新读取图片
//...get file from dfs
} else {
//返回304,告诉浏览器使用本地缓存
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
这种做法的一个缺点就是假设用户在第一次图片下载过程中网络有异常,下载的照片不完整,那用户在刷新,甚至重启浏览器后还是无法获取完整的照片,可能会影响极小部分用户的体验,虽然可以通过ctl+f5忽略Last-Modified或者清空缓存重新下载照片但是大部分普通用户可能不了解这些技巧。
全部回答
- 1楼网友:神也偏爱
- 2021-01-04 09:19
某些浏览器强制离线缓存化!
1)问题发现:
在android自带浏览器、ios自带浏览器和safari浏览器中发现问题:当给一个script指定了src,如果第一次加载失败,则后续同样请求的script标签均不再发生http请求,此后的请求更像一个读取离线缓存请求。这样,如果服务器端内容更新,则浏览器上无法同步。
但chrome、ie等没有此现象,其它具有src或者href的标签或许也有此问题,等后续验证。
这样导致请求重试功能完全失效。当然解决方法可以是:添加如时间戳、随机数等,使每次请求的url变换,跳过此问题。
2)验证问题地址和说明:
这里附带一个我们内部测试的内容,由于服务器端不稳定,因此常常返回两种结果,所以能说明问题,或者大家做一个服务,返回不同的请求时间更能说明问题:
说明:此请求可能返回两种结果,变量d一个包含code标签,一个不包含。但是http头均为200:
1-1)var d={title:"suv...."};
1-2)var d={code:-1}
因此控制台打印的结果可能是:code:-1 和 code:undefined
3)测试和结果:
3-1)测试一:连续静态script请求:五个串行的script,所有浏览器均只请求一次http请求。这个可以说的过去。
script cache
1)问题发现:
在android自带浏览器、ios自带浏览器和safari浏览器中发现问题:当给一个script指定了src,如果第一次加载失败,则后续同样请求的script标签均不再发生http请求,此后的请求更像一个读取离线缓存请求。这样,如果服务器端内容更新,则浏览器上无法同步。
但chrome、ie等没有此现象,其它具有src或者href的标签或许也有此问题,等后续验证。
这样导致请求重试功能完全失效。当然解决方法可以是:添加如时间戳、随机数等,使每次请求的url变换,跳过此问题。
2)验证问题地址和说明:
这里附带一个我们内部测试的内容,由于服务器端不稳定,因此常常返回两种结果,所以能说明问题,或者大家做一个服务,返回不同的请求时间更能说明问题:
说明:此请求可能返回两种结果,变量d一个包含code标签,一个不包含。但是http头均为200:
1-1)var d={title:"suv...."};
1-2)var d={code:-1}
因此控制台打印的结果可能是:code:-1 和 code:undefined
3)测试和结果:
3-1)测试一:连续静态script请求:五个串行的script,所有浏览器均只请求一次http请求。这个可以说的过去。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯