XMLHttpRequest POST multipart/form-data
-
03-07-2019 - |
質問
JavaScript で XMLHttpRequest を使用して、ファイル タイプの入力要素を含むフォームを POST し、ページの更新を回避して有用な XML を取得したいと考えています。
JavaScript を使用してフォームの target 属性を MSIE の iframe または Mozilla のオブジェクトに設定すると、ページを更新せずにフォームを送信できますが、これには 2 つの問題があります。小さな問題は、ターゲットが W3C に準拠していないことです (そのため、XHTML ではなく JavaScript で設定しています)。主な問題は、少なくとも OS X Leopard 上の Mozilla では onload イベントが起動しないことです。さらに、XMLHttpRequest を使用すると、返されるデータが iframe の場合のように XHTML に限定されず、XML になる可能性があるため、より適切な応答コードが作成されます。
フォームを送信すると、HTTP は次のようになります。
Content-Type: multipart/form-data;boundary=<boundary string>
Content-Length: <length>
--<boundary string>
Content-Disposition: form-data, name="<input element name>"
<input element value>
--<boundary string>
Content-Disposition: form-data, name=<input element name>"; filename="<input element value>"
Content-Type: application/octet-stream
<element body>
XMLHttpRequest オブジェクトの send メソッドを取得して上記の HTTP ストリームを複製するにはどうすればよいですか?
解決
'multipart/form-data' リクエストを自分で構築できます (詳細については、次の URL を参照してください)。 http://www.faqs.org/rfcs/rfc2388.html) を使用してください。 send
方法(つまり、xhr.send(あなたのマルチパートフォームデータ))。同様に、より簡単ですが、Firefox 4 以降 (Chrome 5 以降および Safari 5 以降でも) では、 フォームデータ このようなリクエストの構築に役立つインターフェイス。の send
この方法はテキスト コンテンツには適していますが、画像などのバイナリ データを送信する場合は、 sendAsBinary
Firefox 3.0 から使われている方法です。ファイルの送信方法について詳しくは、 XMLHttpRequest
, を参照してください。 http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html.
他のヒント
JavaScript 内のファイル入力フィールドにアクセスする方法はないため、Ajax ファイルのアップロードには JavaScript のみのソリューションはありません。
のような回避策があります iframeを使用する.
iframe (目に見えないもの) がコンテンツではなく XHTML を意味する理由がわかりません。iframe を使用する場合は、onreadystatechange イベントを設定して「完了」を待つことができます。次に、frame.window.document.innerHTML (誰か修正してください) を使用して文字列の結果を取得できます。
var lFrame = document.getElementById('myframe');
lFrame.onreadystatechange = function()
{
if (lFrame.readyState == 'complete')
{
// your frame is done, get the content...
}
};
これを機能させるには、IFrame に POST する必要があります。IFrame ID を指定するターゲット属性をフォームに追加するだけです。このようなもの:
<form method="post" target="myiframe" action="handler.php">
...
</form>
<iframe id="myiframe" style="display:none" />
指定したオンロードイベント、ページまたはiframeにありますか?最初の答えは正しいです。純粋にxmlhttprequestを使用してこれを行う方法はありません。 iframeでは、DOMスクリプトを使用しているかどうかを確認するかどうかを確認してから、メソッドを発射します。
onload イベントを iframe にアタッチするには
if(window.attachEvent){
document.getElementById(iframe).attachEvent('onload', some_method);
}else{
document.getElementById(iframe).addEventListener('load', some_method, false);
}
コンテンツの配置:フォームデータ、名前
次のようにセミコロンを使用する必要があります。コンテンツの配置:フォームデータ;名前
これはFormDataを使用した最新の方法です(完全なドキュメント @MDN)
脚本:
var form = document.querySelector('#myForm');
form.addEventListener("submit", function(e) {
var xhr = new XMLHttpRequest();
xhr.open("POST", this.action);
xhr.addEventListener("load", function(e) {
// Your callback
});
xhr.send(new FormData(this));
e.preventDefault();
});
(この基本形から)
<form id="myForm" action="..." method="POST" enctype="multipart/form-data">
<input type="file" name="file0">
<input type="text" name="some-text">
...
</form>
Alex Polo さんの回答に改めて感謝します