我有一个包含大约 10 个虚拟主机的 nginx 配置,我想让它们共享自定义 404 和 50x 以及维护错误页面。nginx 是一个服务于 angular index.html 的反向代理,我有点困惑如何获取指令error_page 404 /oops/root
以在与网站本身不同的目录中获取字体和图像资产(如果网站根目录返回 404,则无法指向网站目录)。
如果由于任何原因导致应用程序的根目录出现 404,我想在目录内显示自定义 index.html /usr/share/nginx/html/oops
,并能够指向 oops/fonts/* 和 oops/image.svg 和 pngs。
除了资产之外,一切都运行良好。404 页面显示出来,但图像和字体没有正确的路径。似乎无法在 nginx 调试级别日志中看到如何让它们显示出来。
upstream notbrain-api {
server 192.168.1.2:3000;
}
server {
access_log /var/log/nginx/access.log human_json;
error_log /var/log/nginx/error.log debug;
listen 443 ssl;
server_name notbrain.com;
include /etc/nginx/ssl/shared_ssl.nginx;
# font cache fix
location ~* \.(?:woff|eot|ttf|otf) {
root "/usr/local/apps/notbrain.com/dist";
proxy_cache STATIC;
proxy_cache_valid 200 7d;
add_header Vary Accept-Encoding;
add_header Cache-Control public;
}
# proxy to upstream api host
location /api {
proxy_connect_timeout 60;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
expires -1;
add_header Cache-Control "no-store";
proxy_pass http://notbrain-api;
}
location / {
root "/usr/local/apps/notbrain.com/dist";
index index.html;
try_files $uri $uri/ /index.html =404;
expires -1;
add_header Cache-Control "no-store";
}
location ~ \.(aspx|php|jsp|cgi|do|rb)$ {
return 410;
}
# currently working for 404.html, but can't figure out how to point assets to snafu/
# would like to avoid having to explicitly rewrite all images and fonts
#
error_page 404 /snafu/404.html;
location /snafu/ {
# index and assets are inside /usr/share/nginx/html/snafu/[fonts/, images/]
root "/usr/share/nginx/html/";
}
}
答案1
发现是一些变通方法干扰了新的 error_page 节。
首先,我在error_page位置匹配中使用了alias
而不是:root
...
error_page 404 /snafu.html/404.html;
location /snafu.html/ {
alias "/usr/share/nginx/html/snafu.html/";
}
...
然后,在所有错误页面的 HTML 中,我为所有资产加上前缀/snafu.html/
(字体和图像)。
剩下的问题是缺少字体,因为我们有一个针对网络字体缓存问题的解决方案,即不必要地声明root
:
location ~* \.(?:woff|eot|ttf|otf) {
root "/usr/local/apps/notbrain.com/dist";
proxy_cache STATIC;
proxy_cache_valid 200 7d;
add_header Vary Accept-Encoding;
add_header Cache-Control public;
}
上面的内容现在太过激进,并且正在拦截全部字体请求并将根设置为主站点(处于 404 状态)。这需要同时适用于错误页面和站点本身。删除root
并扩展正则表达式以匹配两者即可解决问题:
location ~* ^(.+/)?fonts/(.+)\.(?:woff|woff2|eot|ttf|otf)$ {
proxy_cache STATIC;
proxy_cache_valid 200 7d;
add_header Vary Accept-Encoding;
add_header Cache-Control public;
}
我确信有更优雅的方式来表达,^(.+/)?fonts/(.+)
但这似乎有效。
我不确定为什么更简洁的^(.+)?/fonts/(.+)\.(?:woff|woff2|eot|ttf|otf)$
正则表达式不起作用 - 我的意图是始终以斜杠开头,但前面有一个可选目录。是因为.+
从不匹配斜杠吗?