【Vue.js+Express】historyモードでURLを直接指定したとき404の対策

プログラミング等

どうも、javaしか書けないこじらです。

今回、Vue.jsで作成しているサイトのURLをTwitterでツイートする際、#があると正しい挙動になってくれないことが分かり、hashモードからhistoryモードに移行させることを決めました。

何も分からずこの対応をやっていたので、定番の事象で躓きました。

※追記(2021/03/09):TwitterでサイトURLをツイートするだけであれば、この対応で可能ですが、OGP(SNSでブログカードを表示させたりするためのプロトコル)の対応はVue.js素使いでは難易度が高いです。そのため、この後Nuxt.jsを使用した環境に移行しています。→詳細はこちら

Vue.js + Webpack + npm + Expressみたいな定番の環境ですが、日本語の分かりやすい記事(コピペで脳死できるレベルの記事)がなかったので軽くまとめていきます。

URL直接指定で404

Vue-Routerでただhistoryモードにするだけだと、URL直接指定、もしくはブラウザのリロードで遷移できなくなります。

npm run build → npm startでProduction環境を起動させた場合に発生する事象です。

 

Cannot GET /home

だったり、

GET http://localhost:8080/home 404 (Not Found)
Refused to load the image 'http://localhost:8080/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

だったりといったエラーがコンソールに出力されるかと思います。

 

これはSPAの仕組みに起因します。

 

対処方法としては、サーバ側に設定を追加することです。

404 | Vue Router
The official Router for Vue.js

 

まぁ、上のリンクにある公式のページを見ればやり方が書いてあるんですがw

server.js

Vue.js+npm+WebpackでHerokuにデプロイする際の簡単な方法
どうも、Javaしか書けないVue.js初心者のこじらです。 今回はVue.jsをHerokuにデプロイする方法を書いていきます。 以前からVueアプリをHerokuで動かしていたんですが、毎回「Heroku環境用にソースを書き...

前回の記事でserver.jsを追加し、Expressを使ってアプリを起動させる方法を書きました。

これをベースにhistoryモード対応をします。

connect-history-api-fallback

公式では

「connect-history-api-fallbackを使うといいと思うよ!」

と言っています。

ということでこれをインストール

npm install --save connect-history-api-fallback

そしてserver.jsに、connect-history-api-fallbackを使う宣言します。

 

・server.js

var express = require('express');
var history = require('connect-history-api-fallback');

var app = express();
app.use(history());
var serveStatic = require('serve-static');
app.use(serveStatic(__dirname + "/dist"));
var port = process.env.PORT || 8080;
app.listen(port);
console.log('server started '+ port);

これが変更後のserver.jsです。

主に追加したのは

var history = require('connect-history-api-fallback');
app.use(history());

の2行で、後は順番を整えただけです。

コピペで使えると思います。

 

他の変更点は蛇足になるかと思いますが、まぁ一応書いておきます。

router/index.js

Vue-Routerの方に

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
})

modeとbaseを追加。

 

vue.config.js

前回追記したpublicPathの1行を削除します。historyモードの場合はあかん記述のようです。

  publicPath: "./",

 

これで実装完了です。

私の場合はこれでうまくいきましたが、まだうまくいっていない方は引き続き頑張ってくださいw

 

こじらでした

じゃ

コメント

タイトルとURLをコピーしました