• 通过HTTP Header控制缓存

    我们经常通过缓存技术来加快网站的访问速度,从而提升用户体验。HTTP协议中也规定了一些和缓存相关的Header,来允许浏览器或共享高速缓存缓存资源。这些Header包括:

    • Last-Modified 和 If-Modified-Since
    • ETag 和 If-None-Match
    • Expires
    • Cache-Control
      以上Header又可以分成两种类型:

    • 协商缓存:浏览器发送验证到服务器,由服务器决定是否从缓存中读取,如 1 和 2 。
    • 强缓存:浏览器验证缓存的有效性,然后决定是否从缓存中读取数据,如 3 和 4 。
      本文将会分别介绍这四种配置的作用以及可能产生的影响。

    1、Last-Modified 和 If-Modified-Since
    Last-Modified:服务器在响应请求时,告知浏览器资源的最后修改时间。

    If-Modified-Since:浏览器再次发送请求时,会通过此Header通知服务器在上次请求时所得到的资源最后修改时间。服务器会将If-Modified-Since与被请求资源的最后修改时间进行比对。若资源的最后修改时间晚于If-Modified-Since,表示资源已被改动,则响最新的资源,返回200状态码;若资源的最后修改时间早于或等于If-Modified-Since,表示浏览器端的资源已经是最新版本,响应304状态码,通知浏览器继续使用缓存中的资源。

    2、ETag 和 If-None-Match
    ETag:服务器分配给资源的唯一标识符,资源被修改后,ETag也会随之发生变化。

    If-None-Match:浏览器再次发送请求时,会通过此Header通知服务器已缓存资源的ETag。服务器会将If-None-Match与被请求资源的最新ETag进行比对。若不相同,表示资源已被改动,则响应最新的资源,返回200状态码;若值相同,则直接响应304状态码,通知浏览器继续使用缓存中的资源。

    3、Expires
    服务器可以通过此Header向浏览器传递一个具体的时间(格林威治格式,例如:Thu, 19 Jul 2018 07:43:05 GMT) ,来明确地宣告资源的有效期。在资源过期之前,浏览器不再发送请求,而是直接从缓存中读取数据。只有当资源过期之后,浏览器才会再次向服务器请求该资源。

    4、Cache-Control
    服务器使用此Header来向客户端建议缓存策略,它有一下几个可选值:

    max-age=秒:告知浏览器缓存的有效时长,在该时间内浏览器将直接从缓存中读取数据。

    s-maxage=秒:作用同max-age,但是只对共享高速缓存(如CDN)有效,对浏览器无效。

    no-cache:告知浏览器不要直接使用缓存,而是必须向服务器发送请求。

    no-store:告知浏览器不要缓存本次请求和响应的任何信息。

    public:宣告任何缓存媒介都可以缓存该响应。

    private:宣告该响应只允许个体客户端(如浏览器)去缓存,而不允许共享高速缓存(如CDN)去缓存。

    在上面的介绍中我们了解到浏览器会根据max-age设置的时间进行缓存。而通过研究发现CDN也会识别源站响应头中Cache-Control属性,根据max-age设置的时间进行缓存,但是,如果源站同时设置了s-maxage和max-age,那么CDN会优先采用s-maxage。

    下面通过图例来展示一下这些可选值的效果。

    首先了解一下浏览器是怎样根据max-age进行缓存的:
    通过HTTP Header控制缓存

    从上图不难发现,服务器在Header中返回了Cache-Control: max-age=100后,浏览器成功缓存100秒,该时间段内的请求都从直接以本地缓存来响应。

    那么,服务器在Header中返回Cache-Control:s-maxage=100时,又会对浏览器产生什么样的影响呢?

    通过HTTP Header控制缓存

    如上图所示,浏览器没有采取任何缓存策略,这是因为s-maxage面向的是共享高速缓。

    上面这两个例子很容易理解,在现实世界中,为了加快网站响应速度,我们可能会在浏览器和服务器之间引入CDN服务。浏览器的请求会先到达CDN,然后CDN判断是从缓存中读取数据还是回源到服务器。接下来,让我们看看max-age和s-maxage会对CDN的缓存策略带来哪些影响。
    通过HTTP Header控制缓存

    可以看出CDN也会利用max-age来缓存,所以在100秒内强制刷新浏览器时,CDN会直接用缓存来响应。
    如果服务器使用了s-maxage又会如何呢?
    通过HTTP Header控制缓存

    不难发现CDN对max-age和s-maxage采取了同样的缓存策略,但浏览器并不会根据s-maxage来进行缓存。

    CDN供应商的特殊规则

    我们分别测试了阿里云和腾讯云的CDN对Cache-Control的支持情况,发现他们都有一些独特的规则。

    阿里云CDN可以在控制台里设置Cache-Control,该设置会覆盖源服务器的Cache-Control。

    腾讯云CDN虽然没有再控制台提供覆盖Cache-Control的功能,但其规则却一点也不简单,在使用的时候一定要特别注意:

    • 服务器和CDN均不对缓存进行配置时,CDN会采用默认的缓存机制(静态文件缓存30天,动态请求不缓存);
    • CDN配置缓存机制(但并未开启高级缓存配置)且服务器设置Cache-Control: s-maxage=200,max-age=100时,CDN会按照其控制台设置的规则进行缓存,浏览器则按照max-age进行缓存;
    • 服务器不设置Cache-Control时,CDN会自动在响应的Header中添加Cache-Control: max-age=600,这就会让浏览器将该资源缓存600秒;
    • 服务器设置为禁用缓存时,CDN和浏览器均不进行缓存;
    • 服务器设置Cache-Control: s-maxage=200,max-age=100并开启CDN的高级缓存配置时,CDN会从s-maxage和控制台中设置的缓存时间中选择最小值来作为缓存时间,而浏览器则始终使用max-age;
    • 服务器设置Cache-Control:max-age=100并开启CDN的高级缓存配置时,CDN会从max-age和控制台中设置的缓存时间中选择最小值来作为缓存时间,不影响浏览器的缓存策略。

    组合使用
    如果同时设置了这些Header,浏览器和高速共享缓存会按照下面的优先级进行缓存:
    Cache-Control > Expires > ETag > Last-Modified
    也就是说,Cache-Control不仅是强缓存,而且拥有最高的优先级,我们可以为不经常发生变化的资源应用该Header来提升响应时间。

    在Ada中使用缓存
    Ada提供了UI脚手架和API脚手架,这两类脚手架的服务器端入口文件分别为index.server.js和index.js,我们只需要在入口文件的请求处理函数中为响应添加适当的Header,即可通知客户端进行响应的缓存,比如:

    • // 设置CDN缓存300秒,浏览器缓存200秒
    • ctx.response.headers.set(‘Cache-Control‘, public,s-maxage=300,max-age=200)
    • 在为请求添加缓存Header之前,应该先为其制定适当的缓存策略,需要考虑该URL是否适合缓存(数据是否特定于用户)以及需要缓存的时长等等。

    总结通过使用这些HTTP Header,我们可以主动影响浏览器甚至CDN的缓存策略,从而减少请求数量,提升网页性能,减轻服务器压力。Ada的灵活机制能让我们为不同的URL设置不同的缓存策略,能够更有针对性地进行主动缓存。

    相关文章
    相关标签/搜索
    一,肖一码′期期准香港马会内部免费资枓2019今晚开码结果开奖现场历史开奖资料记录在线查询 天镇县| 扎赉特旗| 永兴县| 和顺县| 栾川县| 怀柔区| 长汀县| 炎陵县| 天水市| 奇台县| 晋宁县| 民权县| 秀山| 军事| 轮台县| 静宁县| 邵武市| 巫山县| 博客| 五华县| 三亚市| 巴青县| 道孚县| 大英县| 奉新县| 南安市| 安阳县| 揭西县| 临西县| 龙井市| 聂拉木县| 古蔺县| 胶州市| 灵山县| 武隆县| 四平市| 射阳县| 石阡县| 全南县| 巴青县| 米易县| 三原县| 呼和浩特市| 长宁区| 黄大仙区| 四会市| 车险| 贵溪市| 黔江区| 九龙县| 景德镇市| 清丰县| 五原县| 鲁山县| 遵义县| 汉中市| 鄂托克旗| 都兰县| 扎赉特旗| 喀喇| 榆社县| 沈阳市| 聂荣县| 宝应县| 报价| 弥渡县| 孟连| 巨野县| 志丹县| 柞水县| 庆城县| 西畴县| 翁源县| 东至县| 高邑县| 遵义市| 交口县| 常宁市| 托里县| 南汇区| 凤山县| 易门县| 海城市| 图们市| 鹤山市| 建宁县| 嘉定区| 南岸区| 龙南县| 高阳县| 青河县| 青川县| 延吉市| 桂林市| 和政县| 威宁| 英山县| 博兴县| 项城市| 全南县| 潜江市| 涡阳县| 合阳县| 荥阳市| 攀枝花市| 时尚| 永和县| 郑州市| 威海市| 潼南县| 南雄市| 罗山县| 河间市| 玛曲县| 汝州市| 东乡| 萨迦县| 安徽省| 溆浦县| 易门县| 周口市| 蒲江县| 阿图什市| 萨嘎县| 金昌市| 巨鹿县| 丘北县| 九龙县| 安丘市| 栖霞市| 侯马市| 合江县| 且末县| 鄂托克旗| 水城县| 东城区| 沈阳市| 尚义县| 奎屯市| 崇左市| 偃师市| 肇东市| 浪卡子县| 鄂温| 苗栗县| 尉氏县| 司法| 商都县| 宜阳县| 林周县| 库尔勒市| 辉县市| 昌乐县| 九江市| 东安县| 闽侯县| 云南省| 嘉兴市| 合作市| 伊川县| 六枝特区| 拜城县| 海兴县| 高淳县| 微山县| 缙云县| 牙克石市| 保靖县| 呼伦贝尔市| 乾安县| 博客| 达拉特旗| 岳阳市| 调兵山市| 东光县| 沁阳市| 监利县| 武冈市| 密山市| 孝昌县| 青州市| 和林格尔县| 靖西县| 平阳县| 阿瓦提县| 扎兰屯市| 本溪市| 巴南区| 依兰县| 江川县| 合阳县| 图片| 陇川县| 广东省| 湘潭市| 泗水县| 池州市| 莎车县| 汕尾市| 衢州市| 永胜县| 邳州市| 文化| 西乌珠穆沁旗| 呈贡县| 沽源县| 阿鲁科尔沁旗| 阳高县| 盐津县| 武威市| 府谷县| 扶沟县| 闸北区| 视频| 吉林市| 喜德县| 龙游县| 通江县| 平安县| 塘沽区| 公主岭市| 三门县| 南通市| 江安县| 汝城县| 崇义县| 泰兴市| 磐石市| 油尖旺区| 淮南市| 屯留县| 南乐县| 长沙县| 习水县| 确山县| 衡山县| 霞浦县| 金坛市| 高密市| 衢州市| 五峰| 尚志市| 凌源市| 岳池县| 大理市| 大宁县| 长沙县| 华宁县| 永靖县| 东乡族自治县| 江山市| 海城市| 湖口县| 五寨县| 金堂县| 乳山市| 棋牌| 新竹县| 桐庐县| 连州市| 宝清县| 巴南区| 花莲县| 逊克县| 青岛市| 莱阳市| 丹东市| 华宁县| 临湘市| 东宁县| 城步| 梅河口市| 通江县| 辽宁省| 江口县| 石嘴山市| 邢台县| 江都市| 长乐市| 寿宁县| 宁远县| 年辖:市辖区| 射洪县| 福建省| 塘沽区| 梁平县| 外汇| 明水县| 科技| 台南县| 五寨县| 济宁市| 丽江市| 普格县| 安阳市| 肇庆市| 潍坊市| 双城市| 稷山县| 丹凤县| 那坡县| 和顺县| 丹江口市| 湄潭县| 娱乐| 新田县| 青神县| 仁化县| 福州市| 朝阳县| 福清市| 开鲁县| 太仓市| 华蓥市| 龙江县| 大悟县| 天气| 姜堰市| 元谋县| 固阳县| 桦甸市| 舞阳县| 茂名市| 巩留县| 陕西省| 渭南市| 柞水县| 永嘉县| 秦皇岛市| 称多县| 青川县| 甘孜| 黄大仙区| 资溪县| 旬邑县| 抚远县| 威远县| 邢台市| 达拉特旗| 赞皇县| 大关县| 沁阳市| 竹北市| 汝城县| 农安县| 蒙自县| 五寨县| 武宣县| 阿荣旗| 习水县| 公主岭市| 台山市| 得荣县| 若羌县| 定襄县| 静安区| 定州市| 仁寿县| 金门县| 无极县| 天台县| 祥云县| 延庆县| 浦东新区| 岑溪市| 乃东县| 洛南县| 文安县| 肃宁县| 新和县| 梅州市| 汕尾市| 邹城市| 诏安县| 卢龙县| 新泰市| 花莲市| 宁德市| 离岛区| 黑龙江省| 桐庐县| 乐山市| 安国市| 建平县| 元氏县| 盈江县| 泾阳县| 鄂州市| 尤溪县| 安徽省| 丘北县| 凤城市| 元谋县| 行唐县| 广丰县| 安溪县| 湘乡市| 洪雅县| 乐至县| 澄江县| 宜君县| 丽江市| 大新县| 泉州市| 应用必备| 武宣县| 上虞市| 华容县| 酉阳| 余干县| 佛山市| 庆城县| 丰镇市| 南京市| 宁海县| 南靖县| 昌乐县| 容城县| 京山县| 万年县| 正定县| 钟山县| 花莲市| 宜州市| 无极县| 上林县| 米脂县| 屏边| 正宁县| 岚皋县| 营山县| 息烽县| 法库县| 波密县| 庐江县| 祁连县| 翁牛特旗| 玛多县| 卢龙县| 曲阜市| 稷山县| 邵阳市| 南部县| 宁强县| 应用必备| 沁源县| 北辰区| 加查县| 宜黄县| 涿州市| 潼南县| 沛县| 蒲城县| 桐乡市| 西乡县| 温宿县| 太原市| 鄄城县| 固始县| 九江市| 珲春市| 上栗县| 平阳县| 阿巴嘎旗| 志丹县| 葫芦岛市| 宜兰县| 宁远县| 岳西县| 宜川县| 抚宁县| 济南市| 吐鲁番市| 娱乐| 文安县| 闻喜县| 安顺市| 深水埗区| 九寨沟县| 会同县| 耒阳市| 锦州市| 刚察县| 胶州市| 广西| 江山市| 乐业县| 同心县| 大安市| 兴仁县| 涞水县| 隆尧县| 前郭尔| 盐源县| 保康县| 余江县| 怀来县| 鲁甸县| 昆山市| 泾阳县| 栖霞市| 荔浦县| 连山| 延吉市| 红安县| 东方市| 沿河| 万盛区| 利辛县| 大宁县| 玛沁县| 大冶市| 鹰潭市| 凌海市| 延安市| 西平县| 健康| 衡水市| 子洲县| 鄂托克前旗| 梧州市| 名山县| 城口县| 老河口市| 武城县| 威海市| 新余市| 竹山县| 即墨市| 东丰县| 渝北区| 原平市| 西安市| 寻甸| 武乡县| 陈巴尔虎旗| 囊谦县| 晋城| 遵化市| 卢湾区| 江源县| 香港| 景德镇市| 乐亭县| 清苑县| 湖南省| 庄河市| 和平县| 锡林郭勒盟| 嘉义市| 石狮市| 益阳市| 辛集市| 会昌县| 漳平市| 建瓯市| 宁武县| 玉树县| 盐边县| 瑞安市| 油尖旺区| 商洛市| 本溪市| 四会市| 山阳县| 收藏| 西青区| 霍林郭勒市| 资兴市| 大邑县| 普宁市| 深圳市| 荆门市| 长治县| 青铜峡市| 洛南县| 扶绥县| 平阳县| 类乌齐县| 合肥市| 三亚市| 金溪县| 江口县| 天津市| 浦东新区| 晋宁县| 高碑店市| 拜泉县| 东至县| 灵寿县| 岗巴县| 长宁县| 潜山县| 华宁县| 上犹县| 永善县| 锦州市| 衡山县| 台东县| 乡宁县| 建瓯市| 武定县| 麦盖提县| 时尚| 陆良县| 台前县| 河源市| 舒城县| 普兰店市| 博湖县| 遂溪县| 衡水市| 芜湖县| 修文县| 耿马| http://wap.jx1870blowv.fun http://3g.jx1870connectv.fun http://wap.jx1870conflictv.fun http://wap.jx1870dov.fun http://3g.jx1870cozzissionv.fun http://wap.jx1870castv.fun http://3g.jx1870eatv.fun http://wap.jx1870checkv.fun http://3g.jx1870clubv.fun http://wap.jx1870bearv.fun http://3g.jx1870blackv.fun http://wap.jx1870attendv.fun http://3g.jx1870beginv.fun http://3g.jx1870concretev.fun http://wap.jx1870contentv.fun http://3g.jx1870cozparev.fun http://jx1870auditv.fun http://www.jx1870displayv.fun