10
5

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 5 years have passed since last update.

Github Pages で .htaccess の代わりに javascript のみでURLの rewrite を実現してパーマリンクを有効にする

Last updated at Posted at 2018-11-24

目的

Github Pages でパーマリンク(整形された動的URL)を使えるようにする。Github Pages では .htaccess などによるURLの rewrite ができないので、同等の機能を javascript のみで実現する。

必要なもの

  • javascript のみ

※ Jekyll は使わない。

仕組み

  1. パーマリンクによる無効なURLを一旦 404.html で受ける(Github Pages のデフォルト仕様)
  2. 404.html に仕込んだ javascript で、クエリストリング付きの有効なURLに変換して目的のページ post.html にリダイレクト
  3. リダイレクトされた目的のページ post.html で、historyAPI の replaceState を使ってURLを最初にリクエストされたパーマリンクに変換

基本構成と各ファイルがやっていること

--
 |-- index.html
 |-- 404.html(無効なパーマリンクを有効なURLに変換してリダイレクト)
 |-- post.html(リクエストされたURLをパーマリンクに再変換)

サンプル

実際に GitHub Pages でサンプルサイトを公開中。

パーマリンクでの遷移を実現するためにやっていることは

  • 404.html
  • post.html

内に記述した下記 javascript のみ。

404.html

/*
 * (JS部分のみ抜粋)
 * パーマリンクをクエリストリング付きのURLに変換してリダイレクト
 */

// リダイレクト先のファイル名
var redirect_file_name = 'post.html';

// リダイレクトで使用するパラメータキー
var parameter_key = 'post_id';

// パーマリンクの取得
var path_name = window.location.pathname;

// クエリストリング付きのURLに変換してリダイレクト
var match_condition = new RegExp(redirect_file_name.replace('.html', '') + '/[a-z0-9-_]+$');
if (permalink = path_name.match(match_condition))
{
  location.href = path_name.replace(permalink, '') + redirect_file_name + '?' + parameter_key + '=' + permalink[0].replace(/post\//, '');
}
post.html

/*
 * (JS部分のみ抜粋)
 * クエリストリング付きのURLをパーマリンクに再変換
 */

// ファイル名
var file_name = 'post.html';

// パラメータキー
var parameter_key = 'post_id';

// URLを取得
var path_name = window.location.pathname;
var query_string = window.location.search;
var base_dir = path_name.split(file_name)[0];

// パーマリンクに再変換
var match_condition = new RegExp(parameter_key + '=[a-z0-9-_]+$');
if (parameter = query_string.match(match_condition))
{
  parameter_value = parameter[0].split('=')[1];
  history.replaceState(null, null, base_dir + file_name.replace('.html', '/') + parameter_value);
  document.title = parameter_value + ' | Github Pages Rewrite';
}

詳しくはこちらのサンプルソースから。

問題点

  • リダイレクトが実行されるので明らかな遷移感がある
  • replaceState が走る前に一瞬変換前のURLが見える(ときもある)

mod_rewrite などWEBサーバのリライト機能と完全に同等というわけではなく、結果として同じことができている、ということ。

その他

Github Pages は拡張子なしのURLを受け付けるので、canonical でURLの正規化さえしておけば固定ページのリライトを意識する必要はなさそう。

どちらも同じリソースを表示する
/contact.html
/contact

さいごに

Jekyllredirect_from のほうがスマートですが、ワイルドカードや正規表現を使ったリダイレクトルールが作れなかったので無理やりこの方法を試してみました。
もっといい方法があればどなたかご教授ください。

そもそも S3Firebase などリライトが可能なサービス使えよ、っていう話ですが、やっぱり CI や Pipeline の設定なしでそのまま本番デプロイできる Github Pages は便利だな、と思うので。
Github さんには rewrite 機能を json で設定できるなどの追加サービスを期待したいです。

以上です。

10
5
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
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?