Vue Router возвращает 404 при переходе к URL-адресу

Я просто включил режим истории маршрутизатора Vue. И он отлично работает, когда я посещаю маршрутизацию vue через v-href или href. Но когда я пытаюсь обновить эту страницу или перейти непосредственно из адресной строки браузера, она просто вернет 404. Есть ли возможность принять обновление/пересмотр этого URL?

Ниже приведена конфигурация маршрутизатора Vue.

var router = new VueRouter({
    hashbang: false,
    history: true,
    mode: 'html5',
    linkActiveClass: "active",
    root:  '/user'
});

Ответ 1

Обновляя страницу, вы делаете запрос на сервер с текущим URL-адресом, а сервер возвращает 404. Вы должны обрабатывать это на своем веб-уровне или уровне веб-сервера.

https://router.vuejs.org/en/essentials/history-mode.html

Ответ 2

Я думаю, что вам не хватает того, что 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>

Надеюсь, это поможет кому-то!

Ответ 3

Если вы действительно не заботитесь о хэше в URL, вы можете просто установить для режима хэш в файле конфигурации маршрутизатора: mode: 'hash' Это прекрасно работает без необходимости настройки на стороне сервера.

const router = new VueRouter({
    routes: Routes,
    mode: 'hash'
});

Режим mode: 'hash' по умолчанию включается в vue, поэтому он должен работать, даже если вы оставите пустым вместо mode: 'hash'.

Ответ 4

Если кто-то имеет дело с этой проблемой в .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

Ответ 5

Для тех, кто видит это с помощью бэкэнда 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)
})

Оба предложения в документации.

Ответ 6

Кто-нибудь еще сталкивался с той же проблемой, я просто понял, что

"book/:bookId/read"  // this will not work after page reload

и это разные

"/book/:bookId/read" // this is what works even after page reload

Это, конечно же, после того, как следуют советам других парней, что более важно, - "поймать весь маршрут" на стороне вашего сервера приложений. Я на самом деле не знаю, почему это сработало, но любой, у кого есть идеи, может дать нам знать.

Ответ 7

Я использую 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" });

        });