Nginx 自定义错误页

默认的 404/502 白底黑字页面既不美观也看不出品牌。用 error_page 把错误码指向自定义页面,配合内部跳转、具名 location,还能实现"后端挂了自动切维护页"这类玩法。

error_page 基本用法

error_page 语法:error_page 错误码... [=响应码] URI;错误发生时 Nginx 对请求做一次内部跳转,加载 URI 对应的页面:

server {
    listen 80;
    root /var/www/html;

    error_page 404 /404.html;          # 404 时内部跳转到站内页面
    location = /404.html { internal; } # 标记 internal,禁止外部直接访问该地址
}

页面文件放 root 目录下,触发验证:

echo "<h1>页面不存在</h1>" > /var/www/html/404.html
curl -s -o /dev/null -w '%{http_code}\n' http://example.com/no-such-page
# 输出:404
curl -s http://example.com/no-such-page
# 输出:<h1>页面不存在</h1>

多个错误码可共用页面,还能用 =code 改写返回给客户端的最终状态码:

error_page 500 502 503 504 /50x.html;       # 四个错误码共用一页
error_page 404 =200 /sorry.html;            # 返回 404 内容但状态改成 200(慎用)
error_page 403 http://example.com/denied;   # 外部重定向,浏览器地址栏会变

后端 502 时显示维护页

默认情况下后端返回的错误响应不会被 error_page 拦截;加 proxy_intercept_errors on 后,后端 4xx/5xx 也交给 error_page 处理:

server {
    listen 80;
    proxy_intercept_errors on;              # 拦截后端错误响应
    error_page 502 503 504 /maintain.html;  # 后端不可用时出维护页

    location = /maintain.html { root /var/www/html; }
    location / {
        proxy_pass http://backend;
    }
}

具名 location @fallback

error_page 的目标也可以是具名 location(以 @ 开头、只能被内部访问),适合做"主后端挂了自动切备用":

server {
    proxy_intercept_errors on;
    error_page 502 @fallback;               # 502 时进入具名 location

    location / {
        proxy_pass http://main_backend;     # 主后端
    }
    location @fallback {
        proxy_pass http://backup_backend;   # 备用后端
    }
}

注意点

  • 自定义页面必须真实存在且路径正确,否则会出现 internal redirection cycle 报错并返回 500。
  • error_page 做的是内部跳转,浏览器地址栏不变;只有写完整 http:// 地址才是外部跳转。
  • 带 always 的响应头(见跨域与安全加固章节)在错误页上同样生效。

小结

自定义错误页三步:准备页面文件 → error_page 错误码 /页面(可用 =code 改状态码)→ 代理后端场景加 proxy_intercept_errors on。需要自动降级时用 @ 具名 location 把 502 导到备用后端即可。

笔记加载中…