IE7のXMLHttpRequestはセキュリティ制限がアップしている?
先週の金曜に書かなかったネタについて、重い腰をあげて書こうと思ったら変なところでハマってしまった。どうもIE7ではXMLHttpRequestを使って「ローカルファイルからローカルファイル」へのアクセスができないようだ。IE6とFirefox2.0にはこのような制限はなく期待通りに動いてくれるのに。
以下、殴り書き
既に読み込み済みのHTMLページにある大量のリンクの情報(href属性やアンカーのテキスト)をJavascriptで取得する場合、方法としては以下のようなものが考えられる。
- document.links を使う。(document.getElementsByTagName("A")でもよい)
- document.body.innerHTML から正規表現で抜き取る。
- XMLHttpRequestで同じページをもう一度読み込み、XMLHttpRequestのresponseTextプロパティから正規表現で抜き取る。
ページに含まれているリンクの数がさほど多くない場合なら1の方法で問題ない。しかし、リンクの数が3777個もあると重くて話しにならなくなってしまう。数千個のDOM要素にアクセスしなければならないからか?
2のinnerHTMLを使う方法も遅い。そのような大きなドキュメントでinnerHTMLを生成することが既に重いのだろう。
一方、3のXMLHttpRequest方式は上の二つに比べてびっくりするぐらい速い。同じページを読むだけだからキャッシュがあるし、余分なDOM処理もないから速いのだと思う。
しかし、前述の通りIE7のXMLHttpRequestでは、ローカルのファイルに対して3の方式は使えなくなる。今回やろうとしているネタでは、その3777個のリンクを1秒程度の時間で抜き出せないとストレス過多になってしまう。1や2では無理で、3なら何とかなるのだが…。
何かいい方法はないだろうか?
追記
1の方法でも、個々のリンクからinnerHTMLを取得せず、子ノードの nodeTypeを見て場合分けをして処理するようにしたらそこそこの速度が出るようになった。単に、innerHTMLへのアクセスが激遅だったようだ。
最終的な性能差は以下の通り。
- 1の方式 : およそ 1500 msec
- 3の方式 : およそ 500 msec
まだ、方式3は3倍程度の時間がかかっているが、とりあえずこれで良しとしよう。続きは、また明日。
今日の教訓:innerHTMLの参照は重い。