独自ドメインで短縮 URL を実現するために、
わざわざデータベース使ってコード作っているのを見かけたので……
数が少なければ、そんな事する必要ないですよね?


短縮 URL について

このブログの記事 URL、SEO 対策なのですが、すっごい長いんですよね~ 😅😖😆

https://blog.balloon.im/2020/02/独自ドメインで独自の短縮-url-を作る方法/

日本語は変換されて、本当の URL はこうなります。

https://blog.balloon.im/2020/02/%E7%8B%AC%E8%87%AA%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%A7%E7%8B%AC%E8%87%AA%E3%81%AE%E7%9F%AD%E7%B8%AE-url-%E3%82%92%E4%BD%9C%E3%82%8B%E6%96%B9%E6%B3%95/

こんなの手入力では無理ですよね!? そういう時に短縮 URL を使うんです。

http://j.mp/tanshukuURL

j.mp は短縮 URL サービスとして有名 bit.ly が提供している独自ドメインです。
bit.ly が当初から提供されている短縮 URL で、それを現在もサービス名としています。

一時短縮 URL サービスが普及していた時期があります。Twitter です。
Twitter は tweet の文字数制限があるので、短縮 URL がよく使われています。
(開始当初は 1 tweet 140 文字にリンクする URL も含まれていました)
でも、Twitter が公式に t.co を採用した事で、サービスの状況が変わりました。

でも、なくなったわけではないのです。
自分がよく見ているのは Windows 10 で PowerShell を起動した時ですね。

PowerShell を起動した時

マイクロソフトは短縮 URL として aka.ms を使っています。
……えっ、ms=マイクロソフト じゃないですか。


前提条件

次の前提です。

  • 転送元・転送先は次で設定
    /example よりも /example1・/example2 は前に記載すると良いでしょう。
    /example で /example1・/example2 が一致してしまう場合があるためです。
転送元 転送先
https://example.org/example1 https://example.net.eu.org/1/
https://example.org/example2 https://example.net.eu.org/2/
https://example.org/example https://example.net.eu.org/
  • 転送元 https://example.org/example の example を任意に設定
    この場合ドメイン example.org へ設定する事になります。
    t.co や bit.ly のようなランダム生成ではありません。
    転送元・先で文字数がほぼ一緒ですが、そこは気にせずに…… 😅
  • 転送は 301 または 302。省略できる時は省略表記も含めて
  • 特別な仕組みを作らず、できるだけシンプルに実現

転送する数は少なめで、テキストエディタ(メモ帳・vi など)で追加して、
容易に実現できる前提です。これなら処理速度も速そうですし。

ある程度数が多くなる短縮 URL の運用であれば、
goo.gl の代わりとして Google さんが提案していた
Firebase Dynamic Links を使ってみるのはいかがでしょうか?

Firebase Dynamic Links


Apache

VPS・専用サーバで VirtualHost 設定済みで、
その独自ドメインの DocumentRoot の場所に .htaccess を入れて実現します。
すでに .htaccess が存在している場合は、ファイルに追記していきます。
Apache 採用のレンタルサーバでも使用可能なので、使えるところは多いでしょう。
確実にログが残るので、使用状況を調査できるメリットもありますね。

Google さんなどで検索すると、Apache の実現方法として
次のような Rewrite を用いた方法がよく出てきます。

RewriteEngine on

RewriteRule ^/example1$ https://example.net.eu.org/1/ [L,R=301]
RewriteRule ^/example2$ https://example.net.eu.org/2/ [L,R=302]
RewriteRule ^/example$  https://example.net.eu.org/   [L,R]

RewriteEngine on は一度記載があれば追記不要です。
R の後ろがない場合は 302 転送になります。

この場合、正規表現を使う必要があります。
完全一致のため、^~$ で囲む感じです。ちょっと面倒なのです。

でも、今回の場合、 Rewrite を使わずに、Redirect で実現できます。

Redirect 301 /example1 https://example.net.eu.org/1/
Redirect 302 /example2 https://example.net.eu.org/2/
Redirect     /example  https://example.net.eu.org/

この方がスッキリするでしょう? Rewrite 無効でも動作します。
英文表記もあり permanent=301、temp=302 です。省略は 302 になります。

Redirect は /example の後ろに文字がある場合、これを継承します。
なので、ドメインの引っ越しをした際の転送例として使われています。

Redirect / https://example.net.eu.org/

Caddy

redir | Caddy Documentation (v2)
http.redir | Caddy Documentation (v1)

Caddy v1・v2 共に Caddyfile へ redir で記載します。
複数のドメイン名があれば、対象ドメイン内の {~} 内に並べていきます。

example.org {
  redir /example1 https://example.net.eu.org/1/ 301
  redir /example2 https://example.net.eu.org/2/ 302
  redir /example  https://example.net.eu.org/
}

301・302 がない場合は 301 転送になります。
gzip (v1) ・ encode zstd gzip (v2) を付けて圧縮しても OK です。
短いヘッダでも意外とレスポンスがはやくなります。

Caddy v2 ではステータスコードを返せるものとして respond もあります。
respond /example "OK" 200 という感じに簡単な返信をファイル生成なしに返せます。

respond | Caddy Documentation (v2)


Firebase Hosting

リダイレクト | Firebase - Hosting 動作をカスタマイズする

先程も記載していた Google さんが提供しているクラウドサービス Firebase、
Hosting で独自ドメイン割り当てと一緒に全体的な転送もコンソールで容易にできますが、
firebase.json に記載する方法で、細かく転送を指定する事もできます。

"hosting": {
  "redirects": [
    { "source": "/example1", "destination": "https://example.net.eu.org/1/", "type": 301 },
    { "source": "/example2", "destination": "https://example.net.eu.org/2/", "type": 302 },
    { "source": "/example",  "destination": "https://example.net.eu.org/",   "type": 301 }
  ]
}

JSON 表記なのでちょっと長くなりますが…… , 区切りで追加していきます。


ZEIT Now (now.sh)

routes | ▲ Docs - Guides - Configuration Reference

now.json に redirects を記載して実現できます。

{
"redirects": [
    { "source": "/example1", "destination": "https://example.net.eu.org/1/", "statusCode": 301 },
    { "source": "/example2", "destination": "https://example.net.eu.org/2/", "statusCode": 302 },
    { "source": "/example",  "destination": "https://example.net.eu.org/" }
  ]
}

こちらも JSON 表記です。
複数ある場合は , で続けます。statusCode がない場合は 308 になります。
(ちなみに 308 は 308 Permanent Redirect で 301 が再定義されたもの)

  "routes": [
    { "src": "/example1", "status": 301, "headers": { "Location": "https://example.net.eu.org/1/" } },
    { "src": "/example2", "status": 302, "headers": { "Location": "https://example.net.eu.org/2/" } },
    { "src": "/example" , "status": 301, "headers": { "Location": "https://example.net.eu.org/" } }
  ]

routes を用いた表記もできます。

ZEIT Now は AWS や GCP を用いています。東京にも CDN があります。
その点ではレスポンスがはやくて安定動作しているかもしれません。

※ 上記は v2 の場合です。v1 を継続使用している場合は異なります。


Netlify

Redirects and rewrites | Netlify docs

Netlify は _redirects ファイルでリダイレクト動作できます。
リダイレクト専門のファイルになっているため、
転送元 転送先 (コード) を並べていくだけの最もシンプルな表記です。

/example1 https://example.net.eu.org/1/ 301!
/example2 https://example.net.eu.org/2/ 302
/example  https://example.net.eu.org/

301! などと ! を付加した場合は、ファイルがあっても無視されます。
ステータスコードがない場合は 301 になります。

次のところで、記載の確認が可能です。

Redirects Headers | Netlify’s playground

GitHub などを使っている人は知ってるサービスだと思います。
GitHub リポジトリに公開して置いておけば、転送先も把握できて安心ですね。

数が多くなければ、今は Netlify で運用し、ソースは GitHub へ push して、
転送先もソースから明確に見えるようにするのが、一番良いのではないでしょうか?
(Netlify は GitHub などで push すると pull して Web 公開する事が容易にできます)

……えっ、使用状況の確認方法?
ドメインを Cloudflare 経由にすれば良いんじゃないですか?

Cloudflare


短縮 URL のテストをする場合……

転送も Web ブラウザのキャッシュに残りますが、
すぐに転送先に変化してしまうので、キャッシュの削除が容易ではなくなります。
そこで、Google Chrome の シークレット ウインドウ を使うと、
キャッシュを参照せず・残さずに最新状態で動作を確認できます。

Google Chrome シークレット ウインドウ


今だったら安値で短縮 URL が運用できる!

数年前まで短縮 URL を行うのには問題があったんですね。
本当に短いドメイン名にしようとするとプレミアムドメイン扱いで
通常は大手企業でないと運用ができなかったのです。\

しかし、現在独自ドメインの種類が増えていて、
(.com .jp などのトップレベルドメインで現在 1500 種類を超えてます)
3~4 文字.種類 であれば、通常価格でも登録しやすくなっています。
ドメイン費用は年間千円~数千円で済む、という事です。探してみて下さい。
でも、有名どころは扱ってるところが少ないです。ここが種類豊富に探せますよ。

また、サーバレベルでも、今はアクセスが多くなっても
CDN(ウェブアクセラレータ)サービスがありますし、
VPS・専用サーバを用いず、Web サービスで容易に実現できる手段もあります。
数が少なめであれば、個人で短縮 URL を運用する事も大変ではないですよ。

とはいっても不特定多数に無料開放して、
登録も自由にしてしまうのは悪用される可能性大なので、
自社・自分制作のサービス専用など限定利用にとどめておくのが無難でしょう。


追加 2020/02/05

優先順位と JSON 表記の考慮で、転送先・転送先を複数記載した内容に修正しました。

あと nginx を入れていなかったので……


nginx

rewrite | nginx Module ngx_http_rewrite_module

通常は rewrite を用います。

server {
  listen 443 ssl;
  server_name example.org;

  rewrite ^/example1$ https://example.net.eu.org/1/ permanent;
  rewrite ^/example2$ https://example.net.eu.org/2/ redirect;
  rewrite ^/example$  https://example.net.eu.org/   permanent;
}

正規表現になるので ^~$ で囲みます。permanent=301、redirect=302 です。

return を用いる方法もあります。if や location で参照元を指定します。

server {
  listen 443 ssl;
  server_name example.org;

  location /example1 {
    return 301 https://example.net.eu.org/1/;
  }
  location /example2 {
    return 302 https://example.net.eu.org/2/;
  }
  location /example {
    return 301 https://example.net.eu.org/;
  }
}