1
0

More than 1 year has passed since last update.

Angularでのルーティング設定とHTTPステータス404(Not Found)対策

Last updated at Posted at 2021-10-06

お勉強したのでメモ書きです。
主にAngularでのHTTPステータス404の対策について記載しているので、興味があれば読んでみてください。

参考(Angular公式サイト)
参考のなったサイト
参考のなったサイト2

ルーティング

ルーティング情報をRoutes配列で定義する
pathやredirectTo、ガード等を定義できる
ここではroutes配列でルーティングを定義している

app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ExampleComponent } from './example/example.component';
import { MainComponent } from './main/main.component';
import { ErrorComponent } from './error/error.component';

const routes: Routes = [
  { path: 'exam', component: ExampleComponent },
  { path: '', component: MainComponent},
  { path: '**', component: ErrorComponent}  //その他は**で表す
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

forRoot()メソッドでルーティング情報付きのRouterModuleモジュールを生成する
forRoot()メソッドはメインモジュールでのみ利用できる。
その他のモジュールでルーティング情報を追加する場合はforChild()メソッドを利用する
構文

forRoot(routes [,config])

ルート設定(引数configの主なパラメーター)

パラメーター名 概要
enableTracing ルーター内部で発生するイベント情報のログ出力をするか
useHash ハッシュモード(「~/#/exam」のようなハッシュ(#~)でパスを表現するモード)を有効にするか
initialNavigation 初期アクセス時にトップページに遷移するか
errorHandler 例外発生時の処理を規定

useHashとNot Found

通常、「http://localhost/」を指定した場合、index.htmlを取得する。(URLは適宜自分の環境で読み替えてください)
ではapp-routing.module.tsで定義したURLを指定した場合どうなるか。
例えば、「http://localhost/exam」を指定した場合http://localhost/exam 404 (Not Found)がブラウザに表示されてAngularアプリケーションが読み込まれない。
これは/examディレクトリのindex.htmlをリクエストしてしまっていることが原因。http://localhost/examと言うURLはhttp://localhost/index.htmlブラウザに読み込まれた後、Angularが書き換えているだけなので、まずはどうにかしてhttp://localhost/index.htmlをサーバーからブラウザに返さないといけない。
(apache等を使わずにng serveを使った場合は404が出力されず、Angularアプリケーションが読み込まれる。存在しないディレクトリにアクセスされたとき、index.htmlを返す設定が組み込まれているらしい。)

http://localhost/exam等、ルーティングで定義したURLを直接指定した場合(ブラウザでリロードF5した場合等)でもindex.htmlを読み込むようにするためには、useHashを使う。
useHashを使うことでURLがhttp://localhost/#/examのようにフラグメント演算子(#)を用いて表現される。

フラグメント演算子より後ろの文字列はサーバー上では認識されないため無視されて、リロードした場合でもhttp://localhost/をリクエストした場合と同じ動作をする。
つまり、index.htmlが読み込まれる。

useHashとブックマーク

ただし、useHashだけではブックマーク等もすべてトップページに遷移してしまう。
これを避けるためにはWEBサーバの設定を変更して、サーバ上に存在しないディレクトリをリクエストした時、アドレスバーの値は変えずにindex.htmlを読み込む設定を加える必要がある。そこで以下のように設定を加える。

例:apacheの場合

httpd.conf
DocumentRoot "/Users/user/OneDrive/Documents/myDocuments/Angular/AngularApplicationProgramming/SampleApp/dist/SampleApp"
<Directory "/Users/user/OneDrive/Documents/myDocuments/Angular/AngularApplicationProgramming/SampleApp/dist/SampleApp">
    RewriteEngine On
    # If an existing asset or directory is requested go to it as it is
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]

    # If the requested resource doesn't exist, use index.html
    RewriteRule ^ /index.html

...
</Directory>

大事なのは以下の部分
存在しないファイル・ディレクトリをリクエストされたとき、/ディレクトリ下(DocumentRoot)にあるindex.htmlを読み込むように設定している。

httpd.conf
    RewriteEngine On
    # If an existing asset or directory is requested go to it as it is
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]

    # If the requested resource doesn't exist, use index.html
    RewriteRule ^ /index.html

apache初心者なりに頑張って意味を解説してみる。
まず、#から始まる行はコメント。
RewriteEngine Onでリダイレクトを設定する機能を開放している。
RewriteCondには条件を記述して、条件に合うときRewriteRuleに従って動作をしている。
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -fの意味は「リクエストされたファイルが存在するときtrue」。
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -dは「リクエストされたディレクトリが存在するときtrue」という意味。
[OR]でつながっているため、リクエストされたファイルorディレクトリが存在するときRewriteRule ^ - [L]すると記述されている。
RewriteRule ^ - [L]は「RewriteRule 正規表現 オプション」の順で記載されている。今回、正規表現はハットのみ(^)。ハットは先頭という意味なので任意の文字に当てはまる。
オプションは- [L]の部分。ハイフンは「オプションの操作だけを実行して、アドレスは置換しない」という意味。[L]はLastを意味し、条件に当てはまるアドレスを書き換えず処理を終了するという意味になる。
つまり、ファイル・ディレクトリが存在するときは何も書き換えられずレスポンスが返されることになる。
また、その次の一文でRewriteCondが指定されずにRewriteRuleが記載されている。つまり、それ以外はRewriteRule ^ /index.htmlすると記載されている。
RewriteRule ^ /index.htmlは任意の文字列を「/index.html」に書き換えるという意味。
これで存在しないファイル・ディレクトリが指定されたときはindex.htmlがレスポンスされるようになった。
試しにリロード(F5)をしたが、404にならずきちんとルーティングで定義したコンポーネントが表示された。
image.png

1
0
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
1
0