Data URI schemeでブラウザから直接開いたHTMLの挙動についてちょっと調べてみた
そもそもData URI scheme とは?
簡単にいうと、画像やらJavaScriptやらそういったHTMLのコンテンツを文字列として定義出来てしまうものです。
フォーマットやら細かいことはこちらのウィキぺディア参照
シンプルなHTMLファイルをData URI schemeで表すと?
こうなります。
data:text/html;charset=UTF-8;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPnRlc3Q8L3RpdGxlPjxib2R5IHN0eWxlPSJjb2xvcjpyZWQiPmh0bWw8L2JvZHk+PC9odG1sPg==
※上記をブラウザのURL欄に張り付ければHTMLが表示されます。(IEだとブラウザが検索で動作してしまって駄目でしたけど、そこはエスケープの仕方でどうにかなるのかな。。。?)
上記のHTMLファイル中でコンテンツの相対パスやJavaScriptのドメインが関連するような仕組みはどうなるのか?
そもそもHTMLそのものを直接表示しているので、URL(パス)が存在しません。
相対パスで書いたコンテンツや、Cookieなどはどうなるのでしょうか?
実際に下記のようなHTMLファイルをData URI schemeに変換して表示してみました。
<html>
<head>
<meta charset="UTF-8">
<title>タイトル</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
div { border-bottom:solid; width:600px; }
img { width:50px; height:50px;}
li { float:left; list-style:none; width:500px; height: 60px; }
.clear { clear:both; }
</style>
</head>
<body>
<div class="clear">コンテンツ読み込み</div>
<ul>
<li class="clear">相対 =></li><li><img src="./relative.png"></li>
<li class="clear">ホスト相対 =></li><li><img src="/absolute.png"></li>
<li class="clear">絶対(http:あり) =></li><li><img src="http://cdn.qiita.com/assets/siteid-reverse-9b38e297bbd020380feed99b444c6202.png"></li>
<li class="clear">絶対(http:なし) =></li><li><img src="//cdn.qiita.com/assets/siteid-reverse-9b38e297bbd020380feed99b444c6202.png"></li>
</ul>
<div class="clear">JavaScript</div>
<ul>
<li class="clear">Cookie(window.document.write(window.document.cookie)) =></li><li><script>window.document.write(window.document.cookie)</script></li>
<li class="clear">ローカルストレージ(window.document.write(window.localStorage)) =></li><li><script>window.document.write(window.localStorage)</script></li>
<li class="clear">セッションストレージ(window.document.write(window.sessionStorage)) =></li><li><script>window.document.write(window.sessionStorage)</script></li>
<li class="clear">Ajax =></li><li><script>$.getJSON('http://express.heartrails.com/api/json?method=getStations&line=JR%E5%B1%B1%E6%89%8B%E7%B7%9A', {}, function(json) { window.document.write(json.response.station[0].name); })</script></li>
<li class="clear">だたの書込み(window.document.write('JavaScript OK')) =></li><li><script>window.document.write('JavaScript OK')</script></li>
</ul>
</body>
</html>
data:text/html;charset=UTF-8;base64,PGh0bWw+PGhlYWQ+PG1ldGEgY2hhcnNldD0iVVRGLTgiPjx0aXRsZT7jgr/jgqTjg4jjg6s8L3RpdGxlPjxzY3JpcHQgc3JjPSJodHRwOi8vYWpheC5nb29nbGVhcGlzLmNvbS9hamF4L2xpYnMvanF1ZXJ5LzIuMS4zL2pxdWVyeS5taW4uanMiPjwvc2NyaXB0PjxzdHlsZT5kaXYgeyBib3JkZXItYm90dG9tOnNvbGlkOyB3aWR0aDo2MDBweDsgfWltZyB7IHdpZHRoOjUwcHg7IGhlaWdodDo1MHB4O31saSB7IGZsb2F0OmxlZnQ7IGxpc3Qtc3R5bGU6bm9uZTsgd2lkdGg6NTAwcHg7IGhlaWdodDogNjBweDsgfS5jbGVhciB7IGNsZWFyOmJvdGg7IH08L3N0eWxlPjwvaGVhZD48Ym9keT48ZGl2IGNsYXNzPSJjbGVhciI+44Kz44Oz44OG44Oz44OE6Kqt44G/6L6844G/PC9kaXY+PHVsPjxsaSBjbGFzcz0iY2xlYXIiPuebuOWvviA9PjwvbGk+PGxpPjxpbWcgc3JjPSIuL3JlbGF0aXZlLnBuZyI+PC9saT48bGkgY2xhc3M9ImNsZWFyIj7jg5vjgrnjg4jnm7jlr74gPT48L2xpPjxsaT48aW1nIHNyYz0iL2Fic29sdXRlLnBuZyI+PC9saT48bGkgY2xhc3M9ImNsZWFyIj7ntbblr74oaHR0cDrjgYLjgoopID0+PC9saT48bGk+PGltZyBzcmM9Imh0dHA6Ly9jZG4ucWlpdGEuY29tL2Fzc2V0cy9zaXRlaWQtcmV2ZXJzZS05YjM4ZTI5N2JiZDAyMDM4MGZlZWQ5OWI0NDRjNjIwMi5wbmciPjwvbGk+PGxpIGNsYXNzPSJjbGVhciI+57W25a++KGh0dHA644Gq44GXKSA9PjwvbGk+PGxpPjxpbWcgc3JjPSIvL2Nkbi5xaWl0YS5jb20vYXNzZXRzL3NpdGVpZC1yZXZlcnNlLTliMzhlMjk3YmJkMDIwMzgwZmVlZDk5YjQ0NGM2MjAyLnBuZyI+PC9saT48L3VsPjxkaXYgY2xhc3M9ImNsZWFyIj5KYXZhU2NyaXB0PC9kaXY+PHVsPjxsaSBjbGFzcz0iY2xlYXIiPkNvb2tpZSh3aW5kb3cuZG9jdW1lbnQud3JpdGUod2luZG93LmRvY3VtZW50LmNvb2tpZSkpID0+PC9saT48bGk+PHNjcmlwdD53aW5kb3cuZG9jdW1lbnQud3JpdGUod2luZG93LmRvY3VtZW50LmNvb2tpZSk8L3NjcmlwdD48L2xpPjxsaSBjbGFzcz0iY2xlYXIiPuODreODvOOCq+ODq+OCueODiOODrOODvOOCuCh3aW5kb3cuZG9jdW1lbnQud3JpdGUod2luZG93LmxvY2FsU3RvcmFnZSkpID0+PC9saT48bGk+PHNjcmlwdD53aW5kb3cuZG9jdW1lbnQud3JpdGUod2luZG93LmxvY2FsU3RvcmFnZSk8L3NjcmlwdD48L2xpPjxsaSBjbGFzcz0iY2xlYXIiPuOCu+ODg+OCt+ODp+ODs+OCueODiOODrOODvOOCuCh3aW5kb3cuZG9jdW1lbnQud3JpdGUod2luZG93LnNlc3Npb25TdG9yYWdlKSkgPT48L2xpPjxsaT48c2NyaXB0PndpbmRvdy5kb2N1bWVudC53cml0ZSh3aW5kb3cuc2Vzc2lvblN0b3JhZ2UpPC9zY3JpcHQ+PC9saT48bGkgY2xhc3M9ImNsZWFyIj5BamF4ID0+PC9saT48bGk+PHNjcmlwdD4kLmdldEpTT04oJ2h0dHA6Ly9leHByZXNzLmhlYXJ0cmFpbHMuY29tL2FwaS9qc29uP21ldGhvZD1nZXRTdGF0aW9ucyZsaW5lPUpSJUU1JUIxJUIxJUU2JTg5JThCJUU3JUI3JTlBJywge30sIGZ1bmN0aW9uKGpzb24pIHsgd2luZG93LmRvY3VtZW50LndyaXRlKGpzb24ucmVzcG9uc2Uuc3RhdGlvblswXS5uYW1lKTsgfSk8L3NjcmlwdD48L2xpPjxsaSBjbGFzcz0iY2xlYXIiPuOBoOOBn+OBruabuOi+vOOBvyh3aW5kb3cuZG9jdW1lbnQud3JpdGUoJ0phdmFTY3JpcHQgT0snKSkgPT48L2xpPjxsaT48c2NyaXB0PndpbmRvdy5kb2N1bWVudC53cml0ZSgnSmF2YVNjcmlwdCBPSycpPC9zY3JpcHQ+PC9saT48L3VsPjwvYm9keT48L2h0bWw+
※サイズを小さくするために、ある程度余計な空白と改行は除去してます。
結果イメージ
結果から見えること
コンテンツ読み込み
パスやプロトコルが関係するような記載方法は読み込みを開始しませんでした。
http:から指定すれば、問題なく読み込むことは出来るようです。
JavaScriptの動作
CookieやらWeb Storage関連は動作しないようです。Consoleにもエラーが出力されていましたが、data:から始まる場合には制限がかけられているようです。
AjaxはSame-Origin Policyに引っかかっているだけのようですので、サーバ側で許可されればデータ取得は出来そうですね。(そういったオープンデータが時間なくて見つけられなかったので、そこまでテストはできませんでしたが。。。)
Uncaught SecurityError: Failed to read the 'cookie' property from 'Document': Cookies are disabled inside 'data:' URLs.
Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Storage is disabled inside 'data:' URLs.
Uncaught SecurityError: Failed to read the 'sessionStorage' property from 'Window': Storage is disabled inside 'data:' URLs.
XMLHttpRequest cannot load http://express.heartrails.com/api/json?method=getStations&line=JR%E5%B1%B1%E6%89%8B%E7%B7%9A. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
その他思った事
まぁなんとなく想定していた範囲の結果でしたが、どこにもコンテンツを配置しなくてもHTMLとして動作させられる事に何か利用価値が無いのかなって思ってたりします。
気になる事が思いついたらまた、検証してみよかと。。。