tinyURL で、長い data スキームを処理させる
忘れたらググればいい に書いてあったことを見て、こんなのを考えてみました。
原理上は、どのような長さの data スキームであっても、 tinyURL で短い URL に変換できるはずです (対応ブラウザなどは調べていません)。
こういうことを tinyURL がよいと思っているかどうか不明なので、 GitHub などには置きません。
自己責任でどうぞ。
長い data スキームであっても tinyURL で処理可能にするスクリプト
できること
原理上、どれだけ長くても tinyURL で data スキームへリダイレクトさせることができます。
例えば、前に作ってみた iPhone Safari 上で動くテトリスでは、 http://tinyurl.com/7zsxzgl
のようになります。
このリンクをクリックすると、 Loading...
と出た後、 data スキームで記述されたテトリスの画面になります。
本題とは関係ないですが、このテトリスは、枠内を、フリック・タップすることで、移動・回転です。
手順
あらかじめ、任意の長さの data スキームに変換済みの HTML ページを用意し、以下のようなコマンドで、 URL が生成されます。
1 | > ruby test.rb data_scheme_file.txt |
なお、 Ruby スクリプト test.rb
は、記事の末尾につけておきます。
原理
概要としては、だいたい以下のようになります。
- data スキームを短い断片に分割し、それぞれを tinyURL で短縮 URL にしておきます。
- トップページとなる Loading 用のページを用意します。最終的に、このトップページを data スキーム化し、 tinyURL で短縮 URL にしたものにユーザーはアクセスします。
このトップページでは、以下のようなことを行います。- JSONP を用いることで、動的に、分割した断片の data スキーム文字列を集めて結合します。
- すべての文字列が結合されたら、
location.replace
で、生成された data スキームにジャンプします。
実際には、リンクリストになるように、少し工夫した断片 tinyURL を生成したりしていますが、原理は以上のようなものです。
スクリプトでは、対象となる data スキームファイルを用意するだけで、上記をすべて自動で行ってくれます。
というような方法で、あらかじめ tinyURL を生成しておけば、 Twitter などでも容易に長いデータや画像などのやりとりができると思います。
なお、繰り返しておきますが、 tinyURL 側が、これを良いと思っているのかどうかは分かりませんし、私も推奨しているわけではありません。
あくまで、技術的にはこういったことができる、ということだとご理解ください。
なお、ターゲットとなる data スキームファイルは、以下のように、 data:
なども付与した状態で作成しておいてください。
data:text/html;base64,PD94bWwgd...
以下にスクリプト test.rb
全文を載せます。 Ruby 1.8, 1.9 で動くはずです。
適当に作ったので、バグなどあるかもしれませんが、ご了承ください。
なお、このスクリプトは、プロキシ下の環境ではうまく動かないかもしれません。
get_tiny_url
の中をプロキシ対応にするのと、12行目の length
を短めにすると、うまく動作すると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # test.rb require( "net/http" ) require( "cgi" ) def get_tiny_url(data) return url end def main(target_filename) length = 3000 target_str = File .open(target_filename){ |f| f.read.gsub( "\n" , "" ) } str_list = [] while (!(target_str.empty?)) str_list.push(target_str.slice!( 0 , length)) end # Get chain of tiny URLs. url = nil str_list.reverse. each do |str| output = << "EOS" callback({url: #{url ? ('"' + url + '"') : 'null'}, data: "#{str}"}); EOS encoded_data = "data:text/javascript;base64," + [ output ].pack( "m" ).gsub( "\n" , "" ) url = get_tiny_url(encoded_data) end # Let's create 'loading' page. output = << "EOS" <! DOCTYPE html> <html> <head> <title>Loading...</title> <script type= "text/javascript" > // <![ CDATA [ var gData = "" ; function load() { var url = "#{url}" ; loadData(url); } function loadData(url) { var elem = document.createElement( "script" ); elem.type = "text/javascript" ; elem.src = url; document.getElementById( "bd" ).appendChild(elem); } function callback(obj) { gData += obj.data; var url = obj.url; if (url){ loadData(url); } else { location.replace(gData); } } // ]]> </script> </head> <body onload= "load()" id= "bd" > <h1>Loading...</h1> </body> </html> EOS encoded_data = "data:text/html;base64," + [ output ].pack( "m" ).gsub( "\n" , "" ) $stdout << get_tiny_url(encoded_data) << "\n" end main( ARGV [ 0 ]) |