XMLHttpRequest.sendAsBinaryでUTF-8と画像のmultipart/form-dataを送信する
ドラッグ&ドロップで画像をアップロードするFirefoxアドオンを製作中につまずいたこと。
テキストのみ、あるいは画像のみを送信するのは特に問題ないのだが、テキストと画像をmultipart/form-dataで送信しようとするとエラーがおきて送信できなかった。マルチバイト文字はjavascript内部ではUnicodeとして扱われているため、UTF-8に変換する必要があるようだ。具体的には以下のようにする。
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"] .createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = "utf-8"; var UTF8ConvertText = converter.ConvertFromUnicode(mb_str);
multipart/form-dataとして送信するには requestbody を
--boundaryString Content-Disposition: form-data; name="text"
UTF8ConvertText --boundaryString Content-Disposition: form-data; name="data"; filename="filename.jpg" Content-Type: image/jpeg
BinaryData --boundaryString--
として
http_request = new XMLHttpRequest(); http_request.open('POST', url, true); http_request.setRequestHeader("Content-type","multipart/form-data; boundary="+boundaryString); http_request.setRequestHeader("Content-length",requestbody.length); http_request.sendAsBinary(requestbody);
で送信する。
他の解決策としては、画像をbase64にする、テキストをURLエンコードするなどがありそうだ。
製作中のドラッグ&ドロップアップロードアドオン利用イメージ

ローカルファイルのアップロード

ブラウザに表示されている画像のアップロード

アップロードされた画像
参考:
[Solved] Problem passing multibyte chars using sendAsBinary