2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VueRouter 404エラー対策

Posted at

VueRouterを使ったデモアプリを作成

フロントはVue.js、バック(RESTAPI)はSpringBootのデモアプリを作りました
アプリケーションはjar実行しています(SpringBoot組み込みTomcatを利用)

トップページのBLOGボタン押下でブログページを表示します
image.png
ブログページはSpringBootで作成したRESTAPIのデータを表示しています
image.png
ブログページに表示している記事はRESTAPIで取得しています
image.png

ページをリロードしようとすると404エラーが発生

ブログページでリロードしようとすると404エラーで白い画面になってしまいます
image.png

この事象はVueRouterのリファレンスでも以下のように説明されています
VueRouterガイド-HTML5 History モード

しかしながら一点問題があります。シングルページのクライアントサイドアプリケーションなので、適切なサーバーの設定をしないと、ユーザーがブラウザで直接 http://oursite.com/user/id にアクセスした場合に 404 エラーが発生します。

router.jsでワイルドカードを指定するだけではダメだった

404エラー時に表示したいエラーページを作成して、router.jsにルーティング設定をしただけでは解消されませんでした

ErrorPage.vue
demo\web\src\pages\ErrorPage.vue
<template>
  <v-app>
    <v-app-bar
        absolute
        color="red lighten-1"
        dark
    >
      <v-toolbar-title>エラーが発生しました</v-toolbar-title>
    </v-app-bar>
    <v-container class="ml-0 mt-16">
      <v-row>
        <v-col cols="12">
          トップページに戻ってください
        </v-col>
      </v-row>
      <v-row>
        <v-col cols="4">
          <v-btn
              color="blue-grey lighten-4"
              width="100"
              v-on:click="clickTopPageBtn"
          >
            top page
          </v-btn>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: "ErrorPage",
  methods: {
    clickTopPageBtn: function () {
      this.$router.push("/")
    }
  }
}
</script>

<style scoped>

</style>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/f0bd6232-bb52-7a21-9866-9f1e08add914.png)
demo\web\src\router.js
import Vue from "vue"
import Router from "vue-router"

import TopPage from "@/pages/TopPage";
import BlogPage from "@/pages/BlogPage";
import ErrorPage from "@/pages/ErrorPage"

Vue.use(Router)

export default new Router({
    mode: "history",
    routes: [
        {
            path: "/",
            name: "トップページ",
            component: TopPage
        },
        {
            path: "/blogPage",
            name: "ブログ",
            component: BlogPage
        },
        {
            path: "*",
            name: "エラーページ",
            component: ErrorPage
        }
    ]
})

Apache .htaccessで解決

Windows用のApacheを導入しました(VueRouter公式ガイドにもWebServerを使えと書いてありましたね…)
Apache+SpringBootJar構成でアプリが動くように設定していきます

AJP通信の設定

今回のアプリはブログページでVue.jsの画面からSpringBootのAPIを呼び出すので
AJP通信を利用してフロントとバックを繋ぎます

ApacheのAJP通信設定

Apacheにはビルド済みVue.jsを配置します
8009ポートでAJP通信できるようにhttpd-proxy-ajp.confを作成します

\httpd-2.4.46-o111h-x86-vc15\Apache24\conf\extra\httpd-proxy-ajp.conf
<Location /blog>
  ProxyPass ajp://127.0.0.1:8009/blog
</Location>

httpd.confでもAJP通信ができるよう修正します

\httpd-2.4.46-o111h-x86-vc15\Apache24\conf\httpd.conf
# 以下のモジュール読み込み箇所のコメントを解除
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
# 末尾に先ほど作成したhttpd-proxy-ajp.confを読み込む設定
Include conf/extra/httpd-proxy-ajp.conf

SpringBootのAJP通信設定

SpringBootの組み込みTomcatでApacheとAJP通信する設定クラスを作成します

demo\src\main\java\com\example\demo\config\AppConfig.java
package com.example.demo.config;

import org.apache.catalina.connector.Connector;
import org.apache.coyote.ajp.AbstractAjpProtocol;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public TomcatServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        Connector ajpConnector = new Connector("AJP/1.3");
        ajpConnector.setPort(8009);
        ajpConnector.setSecure(false);
        ajpConnector.setAllowTrace(false);
        ajpConnector.setScheme("http");
        ((AbstractAjpProtocol) ajpConnector.getProtocolHandler()).setSecretRequired(false);
        tomcat.addAdditionalTomcatConnectors(ajpConnector);

        return tomcat;
    }
}

.htaccess対応

.htaccessにはリダイレクトの設定を記述します
Apacheのドキュメントルートに配置しただけだと.htaccessが適用されません

httpd.confの.htaccess適用設定

httpd.confを以下のように変更します

\httpd-2.4.46-o111h-x86-vc15\Apache24\conf\httpd.conf
# 以下のモジュール読み込み箇所のコメントを解除
LoadModule rewrite_module modules/mod_rewrite.so
# ドキュメントルートのAllowOverride NoneをAllに変更
DocumentRoot "${SRVROOT}/htdocs"
<Directory "${SRVROOT}/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

また、Apacheを配置しているディレクトリにmod_rewrite.soファイルが存在することを確認します
私の環境ではC:\httpd-2.4.46-o111h-x86-vc15\Apache24\modules\mod_rewrite.soでした

.htaccessを作成

VueRouter公式ガイドに記載されている設定内容をそのまま使っています

\httpd-2.4.46-o111h-x86-vc15\Apache24\htdocs.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

このファイルをApacheのドキュメントルートに配置します
私はC:\httpd-2.4.46-o111h-x86-vc15\Apache24\htdocs\に配置しました

これでApacheとアプリケーションの設定は完了です

ApacheにVue.jsリソースを配置

いつも通りnpm run buildを実行すればOKです

cd C:\Users\risab\git\demo\web
npm run build

package.jsonで特に指定していなければビルド済みリソースは\dist配下に出力されます

出力されたビルド済みリソースをApacheドキュメントルートに配置します
image.png

リソースを配置したら、WindowsのサービスからApacheサービスを起動しておきます
Apacheサービス登録は以下のコマンドでできます

cd C:\httpd-2.4.46-o111h-x86-vc15\Apache24\bin
httpd -k install

SpringBootJarを生成

詳細な手順はこちら gradleでjarを生成します

cd C:\Users\risab\git\demo
gradlew bootJar

jarが生成されたら以下のコマンドでアプリケーションを起動します

cd C:\Users\risab\git\demo\build\libs
java -jar demo-0.0.1-SNAPSHOT

これで対策完了!

Apacheにフロントリソースを配置しているのでhttp://localhost/にアクセスします
image.png
VueRouterでページ遷移、AJP通信で画面からバックのAPIも呼び出せています
画面のリロード時も404エラーが発生せず、リロードできるようになっています
image.png
また、存在しないURLにアクセスした場合は.htaccessとVueRouterのワイルドカードが適用されて
エラーページが表示されるようになりました
image.png

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?