まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:html

243 ゲームをご存知でしょうか?
2015092901


2048 ゲームは(そこそこ)有名だと思いますが、そのクローンゲームです。2048 ゲームは以下のルールで遊ぶものです:
(1) 矢印キーを使って、画面内のタイルを4方向にスライドさせる
(2) 同じ数字のタイルをぶつけると、数字が倍の1つのタイルができる
(3) ぶつけて出来上がったタイルの数字が得点になる(2048 タイルを作ることが1つの目標)


243 は 2048 と異なり、3つの同じ数字を重ねることで1つにまとまります。2048 よりは難易度高くなっています。具体的なルールは以下になります:
(1) 矢印キーを使って、画面内のタイルを4方向にスライドさせる
(2) 同じ数字のタイルを3つぶつけると、数字が3倍の1つのタイルができる
(3) ぶつけて出来上がったタイルの数字が得点になる(243 タイルを作ることが1つの目標)



で、このゲームの HTML5 が Github 上で公開されていました。これを使って IBM Bluemix 上で 243 ゲーム環境を作ってみます(まあ、特にトリッキーなこともないんですが・・)。

まず Bluemix 上に 243 ゲームが動くランタイムを作成します。サーバーサイドで動くモジュールがないので、Github の staticfile ビルドパックを使っても動くと思いますが、Bluemix ダッシュボードから PHP ランタイムを選んでも(事実上 PHP を使わないので、かなり贅沢な環境ですが)動きます。今回は PHP ランタイムを使う方向でいきましょう:
2015092902


並行して 243 ゲームの zip モジュールを GitHub からダウンロードします:
2015092903


ダウンロードした zip モジュールを展開します。index.html が存在するディレクトリがドキュメントルートになります:
2015092904


ここまでできたら、cf コマンドラインツールを使って、このドキュメントルートを PHP ランタイムにプッシュするだけ、です:
# cd (展開した index.html があるディレクトリ) ドキュメントルートへ移動
# cf login -a https://api.ng.bluemix.net/    cf で Bluemix にログイン(米国DCの場合)
# cf push (PHP ランタイムの名前)        cf で Bluemix に 243 ゲームをプッシュ

プッシュが成功したら、PHP ランタイムの URL にブラウザからアクセスすると 243 ゲームが始まります:
2015092905


ぎゃー、惜しかったけど無理。難しい!!

僕は1994年に新卒入社しました。Windows95 では搭載PCに初めからモデムが内蔵されていることが多くなり、インターネットのダイアルアップ接続も標準機能になったので楽でしたが、その Win95 がリリースされる前年の、まだ「ダイアルアップ接続するにもモデムを買って、RS232Cで外付けして、フリーソフトをダウンロードして、インストールして、TCP/IP の設定をして・・・」という手続きが必要だった時代です。

・・・と、ここまで書いて「ダイアルアップ接続って何?」と聞かれないか不安になってきました。分からない人はお父さんに聞いてみましょう。 

そんな時代、最初に使ったインターネットブラウザは NCSA Mosaic でした。「HTMLで記述されたウェブページの閲覧ができて、画像まで表示できる!」という、今では普通に行っている作業が 1993 年にできるようになりました。

その NCSA Mosaic の開発に携わったマーク・アンドリーセンが独立して再開発したウェブブラウザが Netscape Navigator(Communicator) でした。Mosaic と比べて圧倒的に速い動作速度に加えて、Java アプレットやJavaScript エンジン、クッキー、フレームといった今でも利用されている機能をいち早く搭載したブラウザでした(1994年)。
svg


このリリースがちょうど自分の新卒入社の時期とも重なり、また運良くそういった関係の業務に新人時代から携わることも出来て、自分は Netscape Navigator でインターネットを使い始めた、という印象が強く残っています。後にリリースされるバージョン 3.0 では電子メールアプリと HTML の WYSIWYG エディタまで内蔵し、Mosaic やまだ機能が未熟だった Internet Explorer との比較で当時のシェアは 70% と言われており、事実上の標準ブラウザでした。


Netscape Navigator を開発していた Netscape Communications 社は後に当時の AOL(現在のタイム・ワーナー)に買収され、Mozilla としてオープンソース化され、その遺伝子の一部は FireFox へと引き継がれていきますが、Netscape Navigator としての進化は完全に終わっていて、歴史の一部になっています。事実、現在では「Netscape Navigator を使ったことのない人」の方が多数派ではないかと思っています。


そんな Netscape Navigator ですが、まだダウンロードすることはできるようです:
http://www.kotalog.net/archives/1601

最終版となった 9.0.0.6 を使ってみました。いつの間にか CSS もサポートされていて、拙作「マンホールマップ」も、ある程度は見れる感じで嬉しい。まあ比較的新しめのライブラリとか、あまり使ってないせいもあるだろうな:
netscape
(画面は Linux 版)

一方、もう一つの拙作で jQuery Mobile 使いまくりの「ねっぴ」の方は画面崩れまくり。jQuery Mobile にはさすがに未対応と見た:
netscape1


この右上の "N" マークが懐かしいなあ・・・

 

ウェブ制作において、画像やサイトの一部を別モーダルウィンドウでプレビューのように表示する、通称「ライトボックス」と呼ばれる機能があります。 具体的にはこんな感じのものです:

マンホールマップ  ←クリックするとライトボックス内でマンホールマップを表示します

↑CSS が適当なので少し見にくいかも。あとスマホだとうまく表示されないかもしれません・・・


元のページに戻ってくることを前提に、違うページの情報を一瞬表示させる、という目的で便利に使える機能です。Facebook などでも写真を表示する時に使われてますね。こういった機能を実現するための JavaScript ライブラリも多く公開されています(ちなみに上記機能は Colorbox というライブラリを使って実現しています)。

Colorbox で iframe を使った簡単な実装例を紹介します。上記ページから js と css をダウンロードし、jQuery と合わせて <head> 内に以下のような記述をしておきます:
<link  href="css/colorbox.css" rel="stylesheet">
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.colorbox-min.js"></script>
<script type="text/javascript">
$(function(){
	$('.box').colorbox( { iframe:true, width:"90%", height:"90%" } );
});
</script>

この例では box というクラスが付与されたリンクに対してライトボックスを実行するような記述になっています。 
その上で以下のような <a> リンクを用意、これだけです:
<a class="box" href="xxx">XXXX</a>


ところが、このライトボックスが使えないページ(ライトボックスの中身として表示できないページ)、というのがたまに存在しています。例えばグーグルのトップページ(http://www.google.co.jp/)です:

Google  ←クリックするとダイアログは表れますが、中に何も表示されません


実は同じようなページは他にもあります。僕が知る限りではアマゾン価格コムのページもライトボックスでは表示されません。

この違いは何でしょうか? 実はページを HTTP リクエストで取得する際のレスポンスヘッダ X-Frame-Optionsによって、そのコンテンツが iframe の内部に表示することを許可するかどうかを制御できます。上記の挙動の違いはこのレスポンスヘッダ X-Frame-Options の値によるものでした。
2014040600


デフォルト値は「なし」です。その場合(つまり特に何もしない場合)、そのページは iframe 内に表示可能です。一方この値が DENY に設定されていると、そのページを iframe 内に表示することはできません。また SAMEORIGIN(生成元と同じフレーム内に限り表示可)や、ALLOW-FROM xxx(生成元が xxx の場合に限り表示可)といった設定も可能です。詳しくはこちらを参照してください。
2014040601


こういう制限をかける側としてはそれなりの意図があって制限しているんでしょうけど、やはり表示できるものなら表示したい、という作成側の意図もあるわけです。また AJAX のクロスドメイン制限にも言えることですが、制限自体は JavaScript での挙動や iframe 内での挙動に制限をかけているだけであって、情報の取得そのものを制限しているわけではないので、回避することもできます。 で、今日はその(X-Frame-Options 制限の)回避に挑戦してみます。

考え方としては iframe での表示に制限をかけられているサイトに対して、Java や PHP などのサーバーサイドプログラミングによって情報を取得(これらには制限がないので可能)し、その結果を iframe 内に入れてしまおう、というものです。まあクロスドメイン対策と同じ考え方です。
2014040602


ということで、上記の紫色の部分を別途作成する(加えて、それをどこかのサーバーに設置しておく)必要があるわけです。この部分は例えば Java のサーブレットであれば、おおまかにはこんな感じになるでしょうかね:
public class SpoofXFrameOptionsServlet extends HttpServlet {
  public void doGet( HttpServletRequest req, HttpServletResponse res ) throws IOException{
    req.setCharacterEncoding( "UTF-8" );

    String html = "";
    String url = "", _url = req.getParameter( "url" );
    if( _url != null && _url.length() > 0 ) url = _url;
    if( url != null && url.length() > 0 ){
      try{
        GetMethod method = new GetMethod( url );
        HttpClient client = new HttpClient();
        int sc = client.executeMethod( method );
        html = method.getResponseBodyAsString();
      }catch( Exception e ){
        e.printStackTrace();
      }
    }

    res.setContentType( "text/html; charset=UTF-8" );
    res.setCharacterEncoding( "UTF-8" );
    res.getWriter().println( html );
}

このサーブレットが http://xxxx/spoofxframeoptions という名前でアクセスできるようになっていたとすると、
http://xxxx/spoofxframeoptions?url=(iframe 内に入れたいページのURL)

のように指定することで、目的のページのコンテンツを取得できることになります。 なので、この上記の URL を iframe 内で指定すればいい、ということになります。
<iframe class="box" href="http://xxxx/spoofxframeoptions?url=(iframe 内に入れたいページのURL)"></iframe>

で、これを実際にやってみたのがこちらのリンクです:
Google  ←ライトボックス内でGoogleトップページが表示できるようになりました

厳密には上記のサーブレットのサンプルはまだ不完全で、実際には文字コードを考慮したり、HTML 内の <base href="..."> 要素を追加する必要があったり、ページによっては Referer を指定しないと取得できなかったり、、、といった細かな修正が必要になるのですが、とりあえず X-Frame-Options の制約を回避する手段としては使えそうですね。


 

このページのトップヘ