ゲレの工房

ゲーム好きの中の人が、自分が作りたいアプリを作る記録です

雑記 : JavaScriptだけで動作する短縮URLサービスを作ろうとしてみた。(その1)

Google短縮URLサービスを終了を宣言し、代わりのサービスを探している方も多いのではないかなと思います。

www.atmarkit.co.jp

短縮URLサービスはいつでも終了する可能性があるものです。それならば、継続的に利用し続けられるサービスを自分で作ってみようと試みた話です。

既存のサービスはどうなっているか

データベースで管理していると思われる

既存の短縮URLサービスでは、おそらくデータベースを使って管理しています。流れとしては

  1. ある程度の長さのランダムな文字列を作る
  2. 短縮する前のURLと生成したランダム文字列を関連づけてデータベースに保存する
  3. サービスドメイン+ランダム文字列が短縮URLとして公開される
  4. サービスドメイン+ランダム文字列のアクセスがきたら、データベースから短縮する前のURLを取り出し、リダイレクトする

このような流れでしょう。確かにこの方法が一番短縮したURLを管理できると思います。もしランダム文字列が全て使われてしまった場合は文字を1つ追加するだけで、さらに無数のURLに対応できてくるわけですから。

ただこの方法では、データベースを使用しなければいけないという問題があります。結局はサーバー維持費がかかるわけですね。私はサーバー維持費をかけないことで、継続的・持続的なサービスを目指したいと考えました。

私の方針

GitHub上でJavaScriptで実行できる短縮URLサービス

GitHubはおそらく当分サービスが続くだろうと思われるサービスです。GitHubでは、HTML+JavaScript+CSSのページを公開することが可能です。しかも無料です。
www.tam-tam.co.jp

基本的にJavaScriptだけで動作する短縮URLサービスを作れば、GitHubなどの静的ページを公開するサービスを使って短縮URLサービスを公開できるのではないかなと考えました。

どう短縮するか

gzipなどで使われる圧縮技術を使ってURLを圧縮してみてはどうか

JavaScriptgzipなどで使われる圧縮技術を実装された先人がいらっしゃいます。
github.com

また、上記のJavaScriptを使い、文字列の圧縮を試した方もいらっしゃいます。こちらも参考にさせていただきました。
setchi.hatenablog.com

実際作ってみた。

汎用短縮URLジェネレータ

https://gelehrtecrest.github.io/surl/

すでにURLが長すぎる気がしますが、そこは無料のGitHubドメインを使っている以上仕方ないということで

ソースコード

メインとして動いているJavaScriptはこちらになります。
https://github.com/gelehrtecrest/surl/blob/master/docs/main.js

短いので貼り付けますね

$(function(){
	var url = location.href;
	var query = location.search;
	if(query.slice(1) != ""){
		location.href=inflate(query.slice(1));
	}
	$('#url').keyup(function() {
		var input_url = $('#url').val();
		$("#shorturl").val(url + '?' + deflate(input_url));
	});
});

function clipboadCopy(string){
	var urltext = document.getElementById(string);
	urltext.select();
	document.execCommand("copy");
	alert("コピーしました");
}

// 圧縮関数
function deflate(val) {
    val = encodeURIComponent(val);
    val = RawDeflate.deflate(val);
    val = btoa(val); // base64エンコード
    return val;
}

// 復号関数
function inflate(val) {
    val = atob(val); // base64デコード
    val = RawDeflate.inflate(val);
    val = decodeURIComponent(val);
    return val;
}
まずわかりやすいところから
  • 圧縮関数と復号関数に関しては、前述のサイトをみてください。
  • clipboadCopyは生成された短縮URLクリップボードにコピーしているだけです。やや蛇足的な関数です。
リダイレクト部分

肝となっているのは$(function(){ で始まる関数の部分です

	var query = location.search;
	if(query.slice(1) != ""){
		location.href=inflate(query.slice(1));
	}

今回はURLの?以降が圧縮された文字列としています。例えば、

https://gelehrtecrest.github.io/surl/?yygpKShWNXYEISM3IErPz0/PSdVLztfLKgAA

というアクセスがあった場合、?yygpKShWNXYEISM3IErPz0/PSdVLztfLKgAA の部分がqueryに入ります。先頭文字は?だと固定してあるので、1文字削ってquery.slice(1)とし、復号関数inflateに入れて、結果をlocation.hrefに入れます。これでリダイレクトができます。ちなみに上記のURLでは、https://google.co.jpにリダイレクトされます。

圧縮部分
         var url = location.href;
~中略~
	$('#url').keyup(function() {
		var input_url = $('#url').val();
		$("#shorturl").val(url + '?' + deflate(input_url));
	});

id="url"のinput要素にURLが書き込まれると、随時圧縮作業が行われて、id="shorturl"のinput要素に圧縮URLが書き込まれます。このときurlにはこのソースコードドメインが入り、間に?が入り、そのあとに圧縮されたURLが入ります。これによって上記のソースコードで説明した query部分で圧縮されたURLを取得し復号することができるのです。

実際どれくらい圧縮されるのかやってみた

ことばエトセトラジェネレータのURLを圧縮してみた

前回のブログ記事で、独自ジェネレータの生成方法の中で、ことばエトセトラジェネレータの話をし、そのURLを書きました。
blog.gelehrte.com

再掲するとこんな感じですね。
https://gelehrtecrest.github.io/countdown-generator/?text=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9&color=white&px=75px&style=&font=%2F1.5%20serif&xpos=16&ypos=36&scale=-2&title=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF&comment=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9%E7%94%A8%E3%81%AE%E7%B0%A1%E6%98%93%E7%9A%84%E3%81%AA%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%A7%E3%81%99

文字数を数えてみました。

$ echo "https://gelehrtecrest.github.io/countdown-generator/?text=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9&color=white&px=75px&style=&font=%2F1.5%20serif&xpos=16&ypos=36&scale=-2&title=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF&comment=%E3%81%93%E3%81%A8%E3%81%B0%E3%82%A8%E3%83%88%E3%82%BB%E3%83%88%E3%83%A9%E7%94%A8%E3%81%AE%E7%B0%A1%E6%98%93%E7%9A%84%E3%81%AA%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%A7%E3%81%99" | wc
       1       1     543

543文字だそうです。

さて、これを今回作った汎用短縮URLジェネレータにかけてみると
https://gelehrtecrest.github.io/surl/?xVHRbsMgDPyaPDZqoCHhkTTJf3SZmyClEBFXTf9+hnVVrWmPUyVkfJwPH2ZCXNZMmkz0tEaYYQoIQ4AV89HidP3IrSdm8FeHn/7mdiM4CCf0IUpkj7BhJttMlJ2kUBcUtGTQ1Aw2+ycUnE2hZmzT/MXGYHQm1OBnMiPb22QRCC8bgaqkTagV7zMke+rs3cOo6Iu8jPt+hWDPxG2LpyG0haL8/p3LmK/DKcl3ZEWhxcdd73rqazHXmoprW649Mtgc+VV9GuLlAu69P1l28RX68LuR6X7Y1NLEs07F4vppMmlNVBy41vzn4F4bVQxq/QU=

あれこれでも長いぞ

文字数は・・・・

echo "https://gelehrtecrest.github.io/surl/?xVHRbsMgDPyaPDZqoCHhkTTJf3SZmyClEBFXTf9+hnVVrWmPUyVkfJwPH2ZCXNZMmkz0tEaYYQoIQ4AV89HidP3IrSdm8FeHn/7mdiM4CCf0IUpkj7BhJttMlJ2kUBcUtGTQ1Aw2+ycUnE2hZmzT/MXGYHQm1OBnMiPb22QRCC8bgaqkTagV7zMke+rs3cOo6Iu8jPt+hWDPxG2LpyG0haL8/p3LmK/DKcl3ZEWhxcdd73rqazHXmoprW649Mtgc+VV9GuLlAu69P1l28RX68LuR6X7Y1NLEs07F4vppMmlNVBy41vzn4F4bVQxq/QU=" | wc
       1       1     359

359文字か・・・・・ちょっと長いですね。

とは言えメリットはあります。

  • 359/543≒0.66 なので、多少なりとも圧縮できている。URL次第ではもっと圧縮される可能性はある(圧縮されない場合もある)
  • gzipと同じ圧縮方式なので、リンクを踏む前に元のURLを確認することができる。(URLの可逆性)

ただ、URLを戻すインターフェイスはまだ未実装です。時間があれば実装したいと思います。

終わりに

前回のブログ記事で長いURLを晒してしまったので、短縮URLサービスを作ろうと思い、今回の記事を書きました。ただ、あまりうまく短縮されないことがわかりました。ただ圧縮方法に関してはもっといろいろ考えることがある気がしますので、後日改良できるアイデアが思いつたら改良したいと思います。

今回はここまで
それではー


広告