nginx vhosts 404 50x 自定义页面带有资产。需要重写吗?

nginx vhosts 404 50x 自定义页面带有资产。需要重写吗?

我有一个包含大约 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)$正则表达式不起作用 - 我的意图是始终以斜杠开头,但前面有一个可选目录。是因为.+从不匹配斜杠吗?

相关内容