Ответ 1
Обновляя страницу, вы делаете запрос на сервер с текущим URL-адресом, а сервер возвращает 404. Вы должны обрабатывать это на своем веб-уровне или уровне веб-сервера.
Я просто включил режим истории маршрутизатора Vue. И он отлично работает, когда я посещаю маршрутизацию vue через v-href или href. Но когда я пытаюсь обновить эту страницу или перейти непосредственно из адресной строки браузера, она просто вернет 404. Есть ли возможность принять обновление/пересмотр этого URL?
Ниже приведена конфигурация маршрутизатора Vue.
var router = new VueRouter({
hashbang: false,
history: true,
mode: 'html5',
linkActiveClass: "active",
root: '/user'
});
Обновляя страницу, вы делаете запрос на сервер с текущим URL-адресом, а сервер возвращает 404. Вы должны обрабатывать это на своем веб-уровне или уровне веб-сервера.
Я думаю, что вам не хватает того, что SPA не является рендерингом на стороне сервера. По крайней мере, для большинства. Таким образом, когда вы получаете доступ/что-либо, ваш веб-сервер не перенаправляет его на index.html. Однако, если вы нажмете на любую ссылку vuejs router, она будет работать из-за того, что 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, вы можете просто установить для режима хэш в файле конфигурации маршрутизатора: mode: 'hash'
Это прекрасно работает без необходимости настройки на стороне сервера.
const router = new VueRouter({
routes: Routes,
mode: 'hash'
});
Режим mode: 'hash'
по умолчанию включается в vue, поэтому он должен работать, даже если вы оставите пустым вместо mode: 'hash'
.
Если кто-то имеет дело с этой проблемой в .NET Core в качестве бэкэнда приложения, хорошим подходом является простой обработчик отката в Startup.cs нашего приложения .NET Core:
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
}));
Или с родным узлом
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)
})
Оба предложения в документации.
Кто-нибудь еще сталкивался с той же проблемой, я просто понял, что
"book/:bookId/read" // this will not work after page reload
и это разные
"/book/:bookId/read" // this is what works even after page reload
Это, конечно же, после того, как следуют советам других парней, что более важно, - "поймать весь маршрут" на стороне вашего сервера приложений. Я на самом деле не знаю, почему это сработало, но любой, у кого есть идеи, может дать нам знать.
Я использую Razor Pages с .net core 2.2, и у меня получилось:
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" });
});
Для Netlify добавьте следующее в файл public/_redirects
...
/* /index.html 200
См https://www.netlify.com/docs/redirects/#history-pushstate-and-single-page-apps