Vue Router return 404 when revisit to the url
我只是启用Vue路由器历史记录模式。 当我通过v-href或href访问vue路由时,它工作正常。 但是,当我尝试刷新该页面或直接从浏览器地址栏进入时,它仅返回404。是否有任何选项可以接受刷新/重新访问该URL?
以下是我的Vue路由器配置
1 2 3 4 5 6 7 | var router = new VueRouter({ hashbang: false, history: true, mode: 'html5', linkActiveClass:"active", root: '/user' }); |
通过刷新页面,您正在使用当前URL向服务器发出请求,并且服务器返回404。您必须在Web框架或Web服务器级别上处理此问题。
https://router.vuejs.org/en/essentials/history-mode.html
我认为您错过了SPA不是服务器端渲染的问题。至少对于大多数人来说。因此,当您访问/ anything时,您的网络服务器不会将其重定向到index.html。但是,如果您单击任何vuejs路由器链接,由于javascript起作用了,而不是服务器端,因此它将起作用。
要解决此问题,请使用.htaccess并将所有请求重定向到index.html,如下所示
1 2 3 4 5 6 7 8 | <ifModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </ifModule> |
希望它能对某人有所帮助!
如果您不太在乎url中的哈希,则可以将模式设置为在路由器配置文件中哈希:
无需设置服务器端即可正常工作。
1 2 3 4 | const router = new VueRouter({ routes: Routes, mode: 'hash' }); |
哈希模式在vue中默认为默认模式,因此即使您保留空白而不是
如果有人将.NET Core作为应用程序的后端处理此问题,则一种不错的方法是.NET Core应用程序的Startup.cs中的简单后备处理程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { ....Your configuration app.UseMvc(routes => { routes.MapRoute( name:"default", template:"{controller=Home}/{action=Index}/{id?}"); }); //handle client side routes app.Run(async (context) => { context.Response.ContentType ="text/html"; await context.Response.SendFileAsync(Path.Combine(env.WebRootPath,"index.html")); }); } } |
有关更多详细信息:http://blog.manuelmejiajr.com/2017/10/letting-net-core-handle-client-routes.html
对于使用Express后端看到此消息的人,中间件connect-history-api-fallback的实现方式如下
1 2 3 4 5 6 7 | const express = require('express'); const history = require('connect-history-api-fallback'); const app = express(); app.use(history({ index: '/' //whatever your home/index path is default is /index.html })); |
或与本机节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | const http = require('http') const fs = require('fs') const httpPort = 80 http.createServer((req, res) => { fs.readFile('index.htm', 'utf-8', (err, content) => { if (err) { console.log('We cannot open"index.htm" file.') } res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }) res.end(content) }) }).listen(httpPort, () => { console.log('Server listening on: http://localhost:%s', httpPort) }) |
两者都是文档中的建议。
如果您具有root用户访问权限,那么最好在Ubuntu上修改
请注意,首先,您必须
1 | sudo a2enmod rewrite |
然后,将以下块添加到
1 2 3 4 5 6 7 8 | <Directory /var/www/html/> RewriteEngine On RewriteBase / RewriteRule ^index\\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </Directory> |
之后,做
1 | sudo systemctl restart apache2 |
对我来说,这是完美无缺的,因为它不仅将Vue创建的路由重定向回
迟到了,但是.....
如果有人对此感兴趣,请执行以下操作:
将对已知客户端URL的请求重定向到索引(但只有已知的客户端URL,这样,您才可以为实际的页面未找到的URL保留404)。您如何执行此操作取决于您的服务器。我当时使用的是Flask,只是添加了更多路线。
向根vue元素添加属性
1 |
我的视图函数将参数替换为URL请求的实际路由的地方
if (this.$el.attributes['redirect_to'].value !=="") path =
this.$el.attributes['redirect_to'].value
this.$router.push(path).catch(err => {})
(需要catch,否则路由器将引发NavigationDuplicated错误。)
之所以这样做,是因为SPA中的URL的全部要点是因为它们指向特定的资源,所以我希望我的用户能够使用URL来返回相同的资源。
希望这可以帮助某人或为他们指明正确的方向,使其适合他们的特定需求。
对于Netlify,将以下内容添加到
1 | /* /index.html 200 |
参见https://www.netlify.com/docs/redirects/#history-pushstate-and-single-page-apps
我正在将Razor Pages与.net core 2.2一起使用,并且可以正常工作:
1 2 3 4 5 6 7 8 9 10 11 12 | app.UseMvc(routes => { routes.MapRoute( name:"default", template:"{controller}/{action=Index}/{id?}"); routes.MapRoute( name:"spa-fallback", template:"{*url:regex(^((?!.css|.map|.js|sockjs).)*$)}", defaults: new { controller ="Index", action ="Index" }); }); |
其他人遇到同样的问题,我才意识到
1 | "book/:bookId/read" // this will not work after page reload |
这是不同的
1 | "/book/:bookId/read" // this is what works even after page reload |
当然,这是在遵循其他向导提出的建议之后,更重要的是在您的应用服务器端捕获所有路由。
我实际上不知道为什么这样做,但是任何有任何想法的人都可以告诉我们。