error_page的配置和常见问题解决方案。
error_page基础配置error_page code [code...] [=response] uri;
http {
# 全局错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
server {
listen 80;
# 指定错误页面的位置
location = /404.html {
root /usr/share/nginx/html;
internal;
}
location = /50x.html {
root /usr/share/nginx/html;
internal;
}
}
}
error_page不生效可能原因及解决方案:
# 错误:使用了proxy_intercept_errors off(默认值)
location / {
proxy_pass http://backend;
proxy_intercept_errors off; # ← 这会导致错误不被nginx拦截
}
# 正确:开启错误拦截
location / {
proxy_pass http://backend;
proxy_intercept_errors on; # ← 关键设置
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
# 错误:可能导致重定向循环
error_page 404 /404.html; # 如果404.html本身不存在,会无限循环
# 解决方案1:确保错误页面存在
location = /404.html {
root /var/www/html;
internal; # 防止直接访问
}
# 解决方案2:使用绝对路径
error_page 404 http://example.com/custom-404.html;
# 解决方案3:设置状态码
error_page 404 =200 /404.html; # 返回200状态码
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_intercept_errors on; # 必须开启
# 处理后端返回的错误
error_page 404 = @fallback;
error_page 500 502 503 504 = @maintenance;
}
location @fallback {
# 返回静态错误页面
root /var/www/error_pages;
try_files /404.html =404;
}
location @maintenance {
root /var/www/error_pages;
try_files /50x.html =500;
}
}
# 使用命名location处理错误
error_page 404 @error_handler;
location @error_handler {
# 记录到日志
access_log /var/log/nginx/errors.log;
# 重写到PHP处理程序
rewrite ^ /error.php?code=$status last;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
include fastcgi_params;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param ERROR_CODE $status;
}
# 捕获多个状态码
error_page 401 403 404 /error.html;
location = /error.html {
internal;
root /usr/share/nginx/html;
# 根据状态码显示不同内容
if ($status = 401) {
set $error_msg "需要登录";
}
if ($status = 403) {
set $error_msg "禁止访问";
}
if ($status = 404) {
set $error_msg "页面不存在";
}
# 可以在HTML中通过变量显示:$error_msg
}
map $http_accept $error_format {
default "html";
"~application/json" "json";
"~application/xml" "xml";
}
server {
error_page 404 = @error;
location @error {
# 根据Accept头返回不同格式
if ($error_format = "json") {
return 404 '{"error": "Not Found", "code": 404}';
}
if ($error_format = "xml") {
return 404 '<?xml version="1.0"?><error><message>Not Found</message><code>404</code></error>';
}
# 默认返回HTML
root /var/www/errors;
try_files /404.html =404;
}
}
# maintenance.conf
error_page 502 503 504 /maintenance.html;
location = /maintenance.html {
root /usr/share/nginx/html;
internal;
}
# 在需要维护时使用
if (-f /var/www/maintenance.flag) {
return 503;
}
http {
# 定义错误页面根目录
error_page 404 /error/404.html;
error_page 500 502 503 504 /error/50x.html;
error_page 403 /error/403.html;
server {
listen 80;
server_name example.com;
# 错误页面目录
location ^~ /error/ {
internal;
root /var/www/html;
}
# 主要应用
location / {
proxy_pass http://backend;
proxy_intercept_errors on;
# 错误处理
error_page 404 = @not_found;
error_page 500 502 503 504 = @server_error;
error_page 403 = @forbidden;
}
# 自定义错误处理location
location @not_found {
# 可以记录日志、统计等
access_log /var/log/nginx/404.log;
# 返回自定义页面
return 302 /error/404.html;
}
location @server_error {
# 发送警报邮件(通过脚本)
# ...
# 返回错误页面
root /var/www/html/error;
try_files /50x.html =500;
}
location @forbidden {
# 重定向到登录页面
return 302 /login?return_url=$request_uri;
}
}
}
# 检查语法
nginx -t
# 详细测试配置
nginx -T
# 重新加载配置
nginx -s reload
# 查看错误日志
tail -f /var/log/nginx/error.log
# 查看访问日志中的错误
grep " 50[0-9] " /var/log/nginx/access.log
# 测试404
curl -I http://localhost/nonexistent
# 测试500错误
curl -I http://localhost/trigger-error
proxy_intercept_errors on 当使用反向代理时
使用internal指令 防止错误页面被直接访问
确保错误页面文件存在 并且有正确的权限
考虑错误页面的缓存策略
记录错误到日志 便于分析
根据业务需求定制错误页面 提供更好的用户体验
需要根据你的具体业务场景选择合适的配置方式。