在Nginx中配置自定义400错误页面时,如果站点启用了SSL,经常会遇到错误页面本身能显示,但里面的CSS、JS或图片等静态资源无法加载的情况。这通常是因为错误响应中资源引用协议不一致,或者Nginx没有正确将静态资源请求放行导致的。

问题产生的原因
当客户端发起HTTPS请求并触发400错误时,Nginx通过error_page指令返回自定义页面。若页面里使用绝对HTTP路径引用资源,浏览器会因混合内容策略阻断加载;若资源路径被错误重定向到错误页本身,也会造成循环或404。
- 错误页中资源使用http://开头,与HTTPS页面冲突
- 静态资源location未排除错误页拦截规则
- error_page配合return导致内部重定向丢失上下文
基础错误页配置
先来看一个最简单的自定义400页面配置,将错误页放在本地,并通过相对路径引用资源。
server {
listen 443 ssl;
server_name www.ipipp.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 自定义400错误页
error_page 400 /error/400.html;
location = /error/400.html {
root /usr/share/nginx/html;
internal;
}
# 静态资源放行
location /error/ {
root /usr/share/nginx/html;
internal;
}
}
错误页中资源引用方式
在400.html中,应使用相对路径或自动协议引用资源,避免写死http。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>400 错误</title>
<link rel="stylesheet" href="/error/style.css">
</head>
<body>
<h1>请求有误</h1>
<p>请检查网址是否正确</p>
<img src="/error/icon.png" alt="提示">
</body>
</html>
使用map统一协议头
若错误页需获知外部协议,可用map提取scheme,但错误页内部资源仍建议用相对路径。
map $scheme $static_proto {
default "https";
http "http";
}
server {
listen 443 ssl;
error_page 400 /error/400.html;
location /error/ {
root /usr/share/nginx/html;
internal;
}
}
调试建议
遇到资源加载问题,可打开浏览器控制台查看Blocked mixed content类报错,并确认Nginx日志中是否有静态资源被导向400.html的记录。通过调整location权限与资源路径,即可在SSL下正常展示自定义400页面及其附属文件。