使用try_files指令
如果你经常在Nginx下部署单页应用(Single Page Application)应用,那么你一定会非常熟悉try_files
这个指令,单页应用的逻辑是不存在的请求资源全部交由index.html
处理
server {
listen 80;
server_name qttc.net;
location / {
root /qttc;
index index.html;
try_files $uri $uri/ /index.html;
}
}
我们使用这个指令同样可以实现请求不存在的图片资源返回一个默认图404.jpg
,配置如下
server {
listen 80;
server_name qttc.net;
location / {
root /qttc;
}
location ~ \.(jpg|jpeg|png|gif)$ {
root /qttc;
try_files $uri /404.jpg;
}
}
测试一下
$ sudo nginx -s reload
$ curl -H 'Host: qttc.net' -i localhost/not-exist-image-resource.jpg
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 26 Jun 2020 07:43:55 GMT
Content-Type: image/jpeg
Content-Length: 22307
Last-Modified: Thu, 25 Jun 2020 11:32:57 GMT
Connection: keep-alive
ETag: "5ef48b69-5723"
Accept-Ranges: bytes
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
$ ll /qttc/404.jpg
-rw-r--r-- 1 root root 22307 6月 25 19:32 /qttc/404.jpg*
从结果可以看出来访问GET /not-exist-image-resource.jpg
不存在图片会响应Content-Type: image/jpg
,通过比对Content-Length: 22307
可以确认返回的就是404.jpg
二进制。再来访问一张存在的图片试一试
$ curl -H 'Host: qttc.net' -i localhost/exist.jpg
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 26 Jun 2020 07:48:25 GMT
Content-Type: image/jpeg
Content-Length: 227099
Last-Modified: Thu, 25 Jun 2020 11:34:20 GMT
Connection: keep-alive
ETag: "5ef48bbc-3771b"
Accept-Ranges: bytes
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
$ ll /qttc/exist.jpg
-rw-r--r-- 1 root root 227099 6月 25 19:34 /qttc/exist.jpg
Okay从结果看来访问一个已存在的资源GET /exist.jpg
响应的Content-Length
与Content-Type
都正确,这段Nginx配置已经可以实现404默认图片
使用error_page
try_files
指令虽然可以实现默认图片返回,但即使不存在的图片总是响应200状态码容易让人有误解,所以能不能即返回默认图片又返回404状态码呢?
可以,使用error_page很轻松就可以实现,配置如下
server {
listen 80;
server_name qttc.net;
location / {
root /qttc;
}
location ~ \.(jpg|jpeg|png|gif)$ {
root /qttc;
error_page 404 /404.jpg;
}
}
来试一下
$ curl -H 'Host: qttc.net' -i localhost/not-exist-image-resource.jpg
HTTP/1.1 404 Not Found
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 26 Jun 2020 07:57:24 GMT
Content-Type: image/jpeg
Content-Length: 22307
Connection: keep-alive
ETag: "5ef48b69-5723"
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
$ curl -H 'Host: qttc.net' -i localhost/exist.jpg
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 26 Jun 2020 07:57:33 GMT
Content-Type: image/jpeg
Content-Length: 227099
Last-Modified: Thu, 25 Jun 2020 11:34:20 GMT
Connection: keep-alive
ETag: "5ef48bbc-3771b"
Accept-Ranges: bytes
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
以上测试分别请求了了两个资源,分别是一个不存在的GET /not-exist-image-resource.jpg
和一个已存在的资源GET /exist.jpg
,结果分别返回正确,并且状态分别是404与200,完美解决问题。