[英]How to handle 404 error request in vuejs SPA with nginx server
我已经设置了我的 vue-cli 版本 3 SPA,以便在我的 routes.js 文件中找不到的任何请求将默认为我的 404 视图,如官方文档中所示:
插入到routes.js
文件底部附近:
{ // catches 404 errors
path: '*',
name: '404',
component: () => import(/* webpackChunkName: "NotFoundComponent" */ './views/NotFoundComponent.vue'),
},
插入nginx配置文件:
location / {
try_files $uri $uri/ /index.html;
}
这成功地提醒用户他们请求的页面不存在。
我的问题:
我希望错误 404 组件返回 404 响应标头(它当前返回 200 状态代码)并将此错误记录到 nginx error.log 文件中。 我想这只能通过使用 nginx 配置来实现。 有没有人实现过这个目标?
我注意到这个问题在 vue-cli 官方文档的下一页中得到了解决,但它只涉及 node express 服务器而不是 nginx: https : //router.vuejs.org/guide/essentials/history-mode。 html#警告
我认为它类似于 Node 解决方案 - 您应该在 nginx 配置中重复所有路由以正确返回 404 状态代码,主要思想是您应该在位置中使用“equals”修饰符并定义error_page
以返回相同的index.html
文件但是带有 404 状态代码,例如:
server {
listen 80;
server_name localhost;
root /my/dir/with/app
error_page 404 /index.html;
location = / {
try_files $uri $uri/ /index.html;
}
location = /books {
try_files $uri $uri/ /index.html;
}
# example nested page
location = /books/authors {
try_files $uri $uri/ /index.html;
}
# example dynamic route to access book by id
location ~ /books/\d+$ {
try_files $uri $uri/ /index.html;
}
}
可能这个配置可以简化或改进,因为我不太擅长 nginx 配置,但它有效。
我通过打破 Vue 生态系统以简单的方式解决了这个问题,否则它将无法工作或需要付出很多努力。
在你的 Vue 路由器中创建以下路由:
{
path: '*',
name: 'PageNotFound',
component: PageNotFound
}
PageNotFound
组件应具有以下代码:
<script>
export default {
name: 'PageNotFound',
created() {
window.location.href = "/404/"
}
}
</script>
nginx 配置应该在获取/404/
路由时返回 404:
server {
...
location ~ ^/404/$ {
return 404;
}
...
}
我不认为它会在服务器端渲染环境中工作。 在这种情况下,您可能需要将包含window.location.href
的语句放在mounted
方法中。
以上答案的注意事项
/notfound
)重新加载页面并不能解决问题,因为这意味着潜在的蜘蛛已经收到了 200。books/123
的图书ID 是否具有正确的格式,但它无法检查books/123
确实存在于后端。这里有两种方法可以解决上述问题
Accept: text/html
返回 index.html 。 然后 Nginx 只需要转发响应。第一个解决方案对于不熟悉 Nginx 的人来说是一种痛苦。 它需要使用 OpenResty 获取 Lua,然后你会再次遇到 Nginx 工作方式的各种怪癖。 你最终会得到很多难以阅读的代码,如果你进一步想要引入缓存,这会变得更加困难。
第二种解决方案更简单。 唯一可能的负面影响是,如果您目前拥有该 API,则您无法从浏览器查看该 API。
nginx.config(当 API 在Accept: text/html
时使用 index.html 响应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。 最后我们直接将响应返回给客户端。
这有以下好处:
Accept: text/html
为任何端点吐出index.html
。此外,您可以更改配置以使 Nginx 在内部遵循重定向,甚至可能不必查看后端 API 以获取永不更改的 URL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.