web-dev-qa-db-ja.com

Vueルーターは、URLに再度アクセスすると404を返します

Vueルーター履歴モードを有効にします。そして、v-hrefまたはhrefを介してvueルーティングにアクセスすると正常に機能します。しかし、そのページを更新しようとするか、ブラウザのアドレスバーから直接アクセスしようとすると、404が返されます。そのURLの更新/再訪問を受け入れるオプションはありますか?

以下は、私のVueルーターの構成です

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

ページを更新すると、現在のURLを使用してサーバーにリクエストを行い、サーバーは404を返します。これは、WebフレームワークまたはWebサーバーレベルで処理する必要があります。

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

22
zxzak

SPAはサーバー側のレンダリングではないということを忘れていると思います。少なくとも大半は。したがって、/ anythingにアクセスすると、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>

それが誰かを助けることを願っています!

14
Tiago Matos

URLのハッシュをあまり気にしない場合は、ルーター設定ファイルでモードをハッシュに設定するだけです。mode: 'hash'サーバー側を設定しなくても正常に機能します。

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

ハッシュモードはデフォルトでvueに付属しているため、mode: 'hash'の代わりに空白のままにしても機能します。

4
Armin

誰かが.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

2
mejiamanuel57

私は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" });

        });
0
irperez

同じ問題に直面している他の誰でも、私はちょうど

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

これは違います

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

これはもちろん、他のファラがそこに提案しているものより重要なことに、アプリサーバー側ですべてのルートをキャッチした後です。私は実際にこれがなぜ機能したのかわかりませんが、どんなアイデアでも私たちに知らせてくれます。

0
Johhn

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)
})

両方とも documentation の提案です。

0
MPawlak