エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

Google Chromeでは(Ajaxで)ローカルファイルにアクセスしようとするとエラーになることについて、他

ちょっとつまずいたので記録。

経緯。

  1. http://textile.thresholdstate.com/マークアップしたテキストをウェブブラウザで表示できないかと考えた(性懲りもなくまた無節操にいろいろ手を出してます)。
  2. Textileを解釈してHTMLに変換してくれるJavaScriptのスクリプトを見つけたので、これを使おうと考えた。
  3. Textileでマークアップしたテキストは表示するHTMLファイルとは別ファイルにしようと考えた。
  4. そこでブラウザで表示されたときにjQuery.getメソッドでTextileで書かれたファイルを読み込もうとした。
  5. Google Chromeを使ってテストしたら表示されなかった。ChromeJavaScriptコンソールを開いてみると「XMLHttpRequest cannot load file:///(中略)/sample.textile. Origin null is not allowed by Access-Control-Allow-Origin.」とエラーになっていた(sample.textileというのが読み込もうとしたファイルのファイル名)。
  6. 念のためFirefoxSafariでためしたらあっさり表示された。
  7. 検索してみたところ、ローカルのファイルの読み込みを許可するには「--allow-file-access-from-files」オプションを指定して起動する必要があるとわかった。
  8. オプションを指定して起動して表示させてみたところ、無事表示できた。


JavaScriptにはまだ詳しくないので断言できませんが、Ajaxでアクセスするばあいの制限のようです。File APIというのを使えば簡単にアクセスできるみたいです(そのばあい今度はSafariが対象外になってしまいますが)。

また、ローカルのファイルと言ってもローカルのHTTPサーバを介して「http://127.0.0.1/sample.html?sample.textile」のようにアクセスするのは問題なくできました。


検索していて、この件について詳しく調べられた方がいらっしゃったのを見つけたのでリンクしておきます。仕様的な背景はこちらを参照してみてください。

また、Google Chromeを「--allow-file-access-from-files」オプションを付けて起動する方法ですが、Microsoft Windows版のばあい、Chromeのショートカットのプロパティにある「リンク先」にある実行ファイル名のうしろにこのオプションを記述したら有効になりました(これがいいやりかたかどうかはわかりませんが)。
Mac OS X版のばあいは…。わたしのMacPowerPCなので悲しいかなChromeが使えません(しくしく)。どなたか教えて頂けたらありがたいです。


(2011/02/21 追記:はてブのコメントで情報頂きました。ありがとうございます)

id:bizarre_sprout File APIでアクセスするときにもChromeは起動オプションが必要。参考:jQuery.load()をChromeで使う時にちょっとハマったこと | バシャログ。


以下、具体的にやったことです。
まず、JavaScriptのライブラリとしてjQueryとTextileをHTMLに変換するスクリプトを用意します。


表示する枠組みとなるHTMLファイルを用意。名前は「sample.html」としておきます。

<html>
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<link rel="stylesheet" type="text/css" href="default.css">
<title id="title"></title>
<script type="text/javascript" src="jquery-1.4.4rc1.js"></script>
<script type="text/javascript" src="textile.js"></script>
<script type="text/javascript">
$(function () {
  var src = location.search.substring(1);
  $.get(src, function(data) {
    $("#title").html(src);
    $("#body").html(convert(data));
  });
});
</script>
</head>
<body id="body">
</body>
</html>

次に、表示させたいTextileでマークアップしたテキストファイルを用意。このファイルの名前は「sample.textile」とします。

h1.見出し1

h1.見出し2

h2.小見出し1

|        |_.Roman|_.Japanese|
|_.italic|_italic_|_日本語_|
|_.strong|*strong*|*日本語*|

お好みでCSSファイルを用意します。ここでは「default.css」という名前で用意。

h1
{
  border-bottom: solid 2px;
}

h2
{
  border-bottom: solid 1px;
}

table
{
  border-collapse: collapse;
}

td, th
{
  padding: 5px;
  border: solid 1px;
}

th
{
  background-color: silver;
}

これら5つのファイルを同じフォルダに置きます。

  • sample.html
  • sample.textile
  • default.css
  • jquery-1.4.4rc1.js
  • textile.js

ブラウザで「sample.html」を開きます。上記のHTMLファイルはURLのクエリで指定されたファイルを読み込むようにしてあるので「file:///(ファイルパス)/sample.html?sample.textile」というように表示させたいファイルをクエリで指定します。Textileで書かれたテキストがtextile.jsで解釈されてHTMLとして表示されます。

開いたイメージ(部分)。