jquery.upload.jsがIEのみで動作しない事象の対応

自宅サーバ-で開発したアプリをレンタルサーバーにインストールしたところ、IEからjQuery.uploadで画像をアップロードする処理が正常に動作しないという現象に遭遇しました。
不思議なことに、ChromeやFirefoxでは全く問題なく動作し、自宅サーバーに接続している限りはIEでも正常に動作します。

アプリの概要としては、よくあるユーザー情報登録系の処理で、利用者の写真をアップロードする際に、画面を更新せずともアップした写真が反映される仕組みの為にjQuery.uploadを使っていました。
また、この部分はライブラリ化されており、過去にも同じ仕組みを使ってプログラムを開発していたので、何が原因なのか分かりませんでした。

早速IEのデバッガを使って調査してみると、handleData関数の最初の処理で躓いていることが分かりました。

if ($.isXMLDoc(contents) || contents.XMLDocument) {
	return contents.XMLDocument || contents;
}

このような処理があり、正常時はここのreturnでサーバーから返却されたXMLがコールバック関数に戻されるようになっています。
しかし、あるサーバーとIEを組み合わせると、このif文の条件に合致せず、その後処理となる戻ってきた文字列をXMLにパースするという処理に流れてしまっていることが判明しました。
(このことから、jQuery.uploadでアップロード処理までは完了しており、その戻り値となるXMLが正常に取得できないということが判明)

ここでパースされる文字列は、単純にサーバーから戻されたXML値が文字列になっているだけかと思ったのですが、それならXMLパース処理で正常にXMLに変換されエラーになることもありません。
ということで調べてみると、ここに渡される文字列は、XMLをIEで表示した際にIEが自動的に加工してしまうHTML形式になっていることも分かりました。

もちろんHTML文字列なので、XMLパース処理は失敗となります。

対応策として、HTML文字列となってしまったXMLから不要なタグを取り除き、XMLに戻してあげるしかありません。
XMLに格納されてくる文字については、こちらが作成したサーバー側の処理で返却する文字列なので、特殊文字等は存在しないことが保障されているので、次のような対応を取りました。
(parseXml関数内のXMLパース処理後に追加)

if (xml.xml == "")
{
	text = text.stripTags();
	text = unescapeHTML(text);
	text = replaceAll(text," ","");
	text = replaceAll(text,"-<","<");
	xml.loadXML(text);
}

また、上記処理で使うunescapeHTML関数も以下のように定義しました。

function unescapeHTML(text)
{
	var div = document.createElement('div');
	div.innerHTML = text;
	return div.childNodes[0] ? (div.childNodes.length > 1 ?
	$A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
	div.childNodes[0].nodeValue) : '';
}

これによって、IEによってHTML化されたXMLを素のXMLに戻し、この文字列をXMLパースすることでXMLとして扱うことが出来るようになりました。
結果は正常に動作しました・・・が、どうもしっくりこない結果に終わりました。

そもそも、サーバが違う(細かく言えばPHPのマイナーバージョンが少し違う程度)でここまで違う動作をするもんかと・・・
IE9に搭載されている非常に強力なデバッガのおかげで無事(?)解決することができましたが、いまだに少し疑問の残る結果とまりました。

This entry was posted in プログラム. Bookmark the permalink.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です