« コナカ(BlogPet) | トップページ | Mash up Award 2nd 審査結果発表 »
2007.03.21
IE7 の XMLHttpRequest と responseXML の謎
XMLHttpRequest を利用する JavaScript (を含む html) を Web サーバ上に置いて、ブラウザからアクセスする分には、IE7 も Firefox 2.x も Opera 9.x も同じような動作をする*1んだけど、全く同じ内容の「JavaScript (を含む html)」をローカルPCに置いたときは挙動が違います。
*1
厳密には、open する URL が同一サーバ内か別サーバかで挙動が違います。同一サーバ内は、IE7 も Firefox 2.x も Opera 9.x も問題なくアクセス可能、別サーバの場合は、IE7 のみ「セキュリティ上の危険があるけど、本当にアクセスしてもいいの?」(ちょっと意訳)みたいなダイアログが出て、「いいよ」と答えるとアクセスできてしまいます。こういう仕様でいいのかなぁ。
ローカルPC上に置いた html ファイル内から JavaScript の XMLHttpRequest を使う場合の挙動の違い
IE6 までは、XMLHttpRequest 相当のことをやろうとすると ActiveXObject("Msxml2.XMLHTTP") か ActiveXObject("Microsoft.XMLHTTP") を使うしか手はなかったんですが、IE7 からはこの方法以外にそのものずばり XMLHttpRequest を使うこともできるようになりました。つまり、両方使えるわけですが、なぜか、ローカルPC に置いた html から使う場合は、挙動が違うんですよね。
IE7 で ActiveXObject("Msxml2.XMLHTTP") を使う場合
responseText は問題なく使える(ローカルPC上にあるテキストファイルを読み出せる)のに、responseXML で XML ファイルを読んでも、中身が空になってしまいます。XML ファイルを responseText で読むと、ちゃんと読めるのに。これは仕様? それともバグ?
で、この XML ファイルを Web サーバ上に置いた(ただし、html + JavaScript 自体はローカルPCに置いたまま)場合は、responseXML でちゃんと XML ファイルの中身が読める。なので、XML ファイルの中身に問題があるとか、そういうことではありません。純粋に XML ファイルの置き場所の違いだけで挙動に違いが発生するという話。
IE7 で XMLHttpRequest を使う場合
なぜか open しようとした時点で「アクセスが拒否されました」というエラーダイアログが表示されます。セキュリティ上の理由か何かで、ローカルPC上のファイルへのアクセスは禁止してるのかな? XML ファイルを Webサーバ上に置くと、問題なくアクセスできるし、responseXML によるファイルの中身の取得もできます。
Firefox の responseXML
ちなみに、Firefox 2 でもちょっと不思議な挙動を観測。FireBug が入ってるかいないかで挙動が違うんですよね。 ローカルファイルに対する responseText は FireBug の有無関係なしにちゃんと動く。一方、responseXML は、FireBug が入ってない時は中身が空、FireBug が入っているときはちゃんと中身が取れる。FireBug を入れると、Firefox の XMLHttpRequest 回りの挙動が変わるなんて、聞いてないよ。
[2007年3月22日追記]
FireBug が入ってない状態でも、prototype.js の Ajax.Request を使った場合は、responseXML の中身、ちゃんと入りますね。prototype.js が何かごにょごにょしてるんだろうなぁ。ソースを確認してみないと。
一方、IE の場合は、prototype.js の Ajax.Request を使っても症状が変わりませんでした(IE7 だけじゃなくて、IE6 も同様の症状が発生することを確認)。MIME type の設定(レジストリ)を確認してみたら、ちゃんと text/xml になってました。なので、MIME type の設定を変えたら直るのでは? という解決策は×です。
[追記、ここまで]
検証用のコード
参考までに、JavaScript を含む html ソースを、以下に示します。
hello.html
<html>
<head>
<meta http-equiv="Content-type" CONTENT="text/html; charset=UTF-8">
<meta http-equiv="Content-script-type" CONTENT="text/javascript">
<title>XMLHttpRequest回りの挙動の違いをチェックする</title>
<script type="text/javascript">
function createHttpRequest(type) {
if ( type == 1 ) {
if( window.XMLHttpRequest )
return new XMLHttpRequest();
if ( window.ActiveXObject ) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {}
}
}
}
else {
if ( window.ActiveXObject ) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {}
}
}
else if( window.XMLHttpRequest )
return new XMLHttpRequest();
}
return null;
}
function getFile(data, method, fileName, async, target, type) {
var request = createHttpRequest(type);
request.open(method, fileName, async);
request.onreadystatechange = function() {
if ( request.readyState == 4 ) {
onLoaded(request, target);
}
}
request.send( data );
}
function onLoaded(request, target) {
if ( target == 1 ) {
var res = request.responseText;
var w = document.getElementById("result");
w.innerHTML = res;
}
else {
var res = request.responseXML;
var w = document.getElementById("result");
w.innerHTML = res.getElementsByTagName("message")[0].firstChild.nodeValue;
}
}
function run(target,location,type) {
var url = location == 1 ? "./" : "http://localhost:8080/test/";
url += target == 1 ? "hello.txt" : "hello.xml";
getFile("", "GET", url, false, target, type);
}
function clear() {
var w = document.getElementById("result");
w.innerHTML = "";
}
</script>
</head>
<body>
<form id="form111" action="javascript:run(1,1,1)" method="get">
<input type="submit" value="XMLHttpRequest,ローカルtxt 実行">
</form>
<form id="form112" action="javascript:run(1,1,2)" method="get">
<input type="submit" value="Msxml2.XMLHTTP,ローカルtxt 実行">
</form>
<form id="form121" action="javascript:run(1,2,1)" method="get">
<input type="submit" value="XMLHttpRequest,リモートtxt 実行">
</form>
<form id="form122" action="javascript:run(1,2,2)" method="get">
<input type="submit" value="Msxml2.XMLHTTP,リモートtxt 実行">
</form>
<form id="form211" action="javascript:run(2,1,1)" method="get">
<input type="submit" value="XMLHttpRequest,ローカルxml 実行">
</form>
<form id="form212" action="javascript:run(2,1,2)" method="get">
<input type="submit" value="Msxml2.XMLHTTP,ローカルxml 実行">
</form>
<form id="form221" action="javascript:run(2,2,1)" method="get">
<input type="submit" value="XMLHttpRequest,リモートxml 実行">
</form>
<form id="form222" action="javascript:run(2,2,2)" method="get">
<input type="submit" value="Msxml2.XMLHTTP,リモートxml 実行">
</form>
<div id="result"></div>
<form id="form999" action="javascript:clear()" method="get">
<input type="submit" value="消去">
</form>
</body>
</html>
hello.txt
こんにちはこんにちは!!
hello.xml
<?xml version="1.0" encoding="UTF-8"?> <message> こんにちはこんにちは!! </message>

responseXML の中身が空のときに発生するエラーをデバッガで解析している様子
投稿者: tsupo 2007.03.21 午後 11:22
| 固定リンク
|
|
| ![]()
|
|
アマゾンわくわく探検隊
トラックバック
この記事のトラックバックURL:
この記事へのトラックバック一覧です: IE7 の XMLHttpRequest と responseXML の謎:
コメント
ieは隠しセキュリティゾーンとしてマイコンピュータをもってますよ
昔から
投稿者: test (2008.07.08 午前 04:35)



