我只是启用了Vue路由器历史记录模式。当我通过v-href或href访问vue路由时,它工作正常。但是,当我尝试刷新该页面或直接从浏览器地址栏,它只返回404.是否有任何选项接受刷新/重新访问该网址?
以下是我的Vue路由器配置
var router = new VueRouter({
hashbang: false,
history: true,
mode: 'html5',
linkActiveClass: "active",
root: '/user'
});
通过刷新页面,您使用当前URL向服务器发出请求,服务器返回404.您必须在Web框架或Web服务器级别上处理此问题。
我想你错过了SPA不是服务器端渲染。至少对大多数人而言。因此,当您访问/任何内容时,您的Web服务器不会将其重定向到index.html。但是,如果你点击任何vuejs路由器链接,它将工作,因为javascript开始行动,而不是服务器端。
要解决此问题,请使用.htaccess并将所有请求重定向到index.html
<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中的hash,你可以在你的路由器配置文件中设置hash模式:mode: 'hash'
这样可以正常运行而无需设置服务器端。
const router = new VueRouter({
routes: Routes,
mode: 'hash'
});
默认情况下,哈希模式在vue中出现,因此即使您留空而不是mode: 'hash'
它也应该有效。
如果有人在.NET Core中将此问题作为应用程序的后端处理,那么一个很好的方法是在.NET Core应用程序的Startup.cs中使用一个简单的回退处理程序:
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
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
}));
或者使用Native Node
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)
})
两者都是documentation的建议。
其他任何人面临同样的问题,我才意识到这一点
"book/:bookId/read" // this will not work after page reload
这是不同的
"/book/:bookId/read" // this is what works even after page reload
这当然是在遵循了其他人提出的建议之后,更重要的是在您的应用服务器端捕获所有路线。我实际上不知道为什么会这样,但任何有想法的人都可以告诉我们。
我正在使用.net核心2.2的Razor页面,我得到了这个工作:
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" });
});