Hot For Coding

Nginx使用try_files与error_page自定义404图片

full nginx 404 jpg

使用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 625 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 625 19:34 /qttc/exist.jpg

Okay从结果看来访问一个已存在的资源GET /exist.jpg响应的Content-LengthContent-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,完美解决问题。

分享

TITLE: Nginx使用try_files与error_page自定义404图片

LINK: https://www.qttc.net/532-custom-404-image-with-try-files-and-error-page-on-nginx.html

NOTE: 原创内容,转载请注明出自琼台博客