http - 如何设置nginx仅在修改时传输静态文件
问题描述
我正在使用 nginx 来提供文件夹。我正在通过其他进程更改文件夹中的文件。我想以这样一种方式设置 nginx,即如果服务器上的文件未更改,则文件内容不会通过 http 发送。当文件改变时(即修改日期已经改变),文件被传输。我查看了一些文档并进行了一些谷歌搜索,但还没有找到适合这种情况的方法。大多数时候人们都在清除缓存文件夹,但这对我来说似乎不是很优雅。是否可以通过 304/200 代码进行组织?即,如果文件被更改,服务器将使用 HTTP 200 及其内容进行响应,否则使用 HTTP 304。
解决方案
如何配置:
这已经是默认行为;为此,客户端必须根据ngx_http_not_modified_header_filter()和http://nginx.org/r/if_modified_sinceIf-Modified-Since
发送和/或If-None-Match
ETag
标头。
如何测试:
您可以通过查找给定资源的字段来轻松地使用curlLast-Modified
进行测试,然后在标头中使用exact
相同日期对相同资源发出后续请求(分别与和相同)。If-Modified-Since
ETag
If-None-Match
用于curl
测试If-Modified-Since
/ Last-Modified
:
%curl -i bmap.su | & fgrep -e Date -e HTTP -e Length -e Modified
HTTP/1.1 200 OK
Date: Sat, 10 Aug 2019 04:20:17 GMT
Content-Length: 12842
Last-Modified: Tue, 09 Apr 2013 17:18:16 GMT
%curl -i -H"If-Modified-Since: Tue, 09 Apr 2013 17:18:16 GMT" bmap.su | & fgrep -e Date -e HTTP -e Length -e Modified
HTTP/1.1 304 Not Modified
Date: Sat, 10 Aug 2019 04:20:41 GMT
Last-Modified: Tue, 09 Apr 2013 17:18:16 GMT
%curl -i -H"If-Modified-Since: Tue, 09 Apr 2013 17:18:17 GMT" bmap.su | & fgrep -e Date -e HTTP -e Length -e Modified
HTTP/1.1 200 OK
Date: Sat, 10 Aug 2019 04:27:47 GMT
Content-Length: 12842
Last-Modified: Tue, 09 Apr 2013 17:18:16 GMT
在上面的例子中:
我们首先查看
Last-Modified
资源的日期。我们使用与先前响应标头中的日期相同
If-Modified-Since
的请求标头发出后续请求;请注意,我们得到了一个响应,正如缺少字段所期望的那样,它没有附带任何响应主体,从而节省了带宽。Last-Modified
304 Not Modified
Content-Length
我们最终测试了 nginx 对这个特性的默认设置;根据http://nginx.org/r/if_modified_since,
exact
默认匹配;因此,如果我们提供了一个不准确的日期(无论是较早的还是较晚的),那么我们将返回200 OK
一个完整的响应正文(这通常是您想要的,以避免在Last-Modified
日期恢复时缓存中毒到更早的一个)。
用于curl
测试If-None-Match
/ ETag
:
%curl -i nginx.org | & fgrep -e HTTP/ -e Date: -e Server: -e Length: -e Modified: -e ETag:
HTTP/1.1 200 OK
Server: nginx/1.15.7
Date: Sat, 10 Aug 2019 05:24:06 GMT
Content-Length: 9053
Last-Modified: Tue, 23 Jul 2019 12:20:32 GMT
ETag: "5d36fb90-235d"
%curl -i -H "If-None-Match: 5d36fb90-235d" nginx.org | & fgrep -e HTTP/ -e Length: -e Modified: -e ETag:
HTTP/1.1 200 OK
Content-Length: 9053
Last-Modified: Tue, 23 Jul 2019 12:20:32 GMT
ETag: "5d36fb90-235d"
%curl -i -H 'If-None-Match: "5d36fb90-235d"' nginx.org | & fgrep -e HTTP/ -e Length: -e Modified: -e ETag:
HTTP/1.1 304 Not Modified
Last-Modified: Tue, 23 Jul 2019 12:20:32 GMT
ETag: "5d36fb90-235d"
这是我们在上面所做的:
第一步,我们通过
ETag
响应头请求查找实体标签;见https://en.wikipedia.org/wiki/HTTP_ETag。第二步,我们使用请求头
ETag
中提供的内容If-None-Match
发出请求;请注意,我们忘记在它周围加上引号,这显然是强制性的,对于 nginx 和 Apache(可以很容易地根据 httpd.apache.org 主机进行验证)。在第三步中,我们使用实际的
If-None-Match
请求标头发出正确的更正请求HTTP/1.1 304 Not Modified
,并按预期接收带正文的响应。
推荐阅读
- android-studio - Android Studio,Github 登录问题,凭据不正确
- vue.js - 如何显示值也是数组的对象数组
- docker - Docker 项目容器 nginx conf 引用完全不同的项目。在 mac 上运行(这真的很奇怪!)
- react-hooks - 当其中包含“document.addEventListener”时,如何测试 useEffect React 挂钩?
- android - 在 build.gradle 文件的 externalNativeBuild 中指定目标-> 没有方法签名
- python - 如何以这种格式将字典信息写入文本文件?(Python)
- selenium - 带有 clj-webdriver 和 chromedriver 的 Selenium 3.141.59 在未从 Guava 中找到的方法上失败
- java - 我可以使用 indexOf() 在 for 循环中返回两个不同的值吗?
- c++ - c++ 检查数组是否等于未创建的数组
- java - 您如何在所有活动中使用工具栏