对于遇到此问题并为您节省数小时头痛的人。
上述答案的注意事项
- 简单地用新的 URL(例如
/notfound)重新加载页面并不能解决问题,因为这意味着潜在的蜘蛛已经收到 200。
- 简单地复制路线是一个半解决方案。这适用于永远不会更改的 URL,并通过检查 URL 结构的有效性。因此,例如,它可以检查书籍 ID
books/123是否具有正确的格式,但无法检查books/123后端是否确实存在。
这里有两种方法可以解决上述问题
- 让 Nginx 向后端发出镜像子请求,以检查资源是否实际存在。然后总是返回 index.html 但带有来自子请求响应的状态。这对 Nginx 来说非常棘手,因为从设计上来说,它很难组合答案。
- 让后端 API 返回 index.html 的
Accept: text/html. 然后 Nginx 只需要转发响应。
第一个解决方案对于不熟悉 Nginx 的人来说是一件很痛苦的事情。它需要使用 OpenResty 获取 Lua,然后你会再次遇到 Nginx 工作方式的各种怪癖。你最终会得到很多难以阅读的代码,如果你更想引入缓存,那就更加困难了。
第二种解决方案更容易。唯一可能的负面因素是,如果您当前拥有该 API,则无法从浏览器查看 API。
nginx.config(当 API 响应 index.html on 时Accept: text/html)
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
rewrite ^(.*) /api$1 break;
proxy_set_header "Accept" "text/html";
proxy_pass http://localhost:8000;
}
在这种情况下,Nginx 将首先尝试提供文件,如果它在本地找不到它,它将通过后备。
在回退中,我们重写 URI 以匹配后端服务器的期望。在此示例中,我api/在每个请求之前添加。然后我添加标头Accept: text/html,以便后端 API 将使用 index.html 而不是 JSON 进行响应。最后我们直接将响应返回给客户端。
这有以下好处:
- 它不依赖于 Nginx,因此可以与任何反向代理一起使用。最重要的是它不依赖代理服务器来拥有某些功能。
- 即使在没有运行 Nginx 的情况下也可以在开发过程中工作。
- 易于编写测试。
index.html你只需要测试你的后端 API 以在给定Accept: text/html任何端点时吐出。
- 不需要您使用每个新端点手动更新 Nginx 配置。
此外,您可以更改配置以使 Nginx 在内部遵循重定向,甚至可能不必查看后端 API 以获取永远不会更改的 URL。