1. ホーム
  2. javascript

[解決済み] jQueryのAjax-requestsでFormDataオブジェクトを送信する方法は?[重複している]をクリックします。

2022-03-18 15:32:23

質問

XMLHttpRequestレベル2 規格 (まだ作業中の草案) では FormData インタフェースがあります。このインタフェースは File オブジェクトをXHR-requests (Ajax-requests)に追加します。

過去には、"hidden-iframe-trick"が使用されていました(これについては その他の質問 ).

このような仕組みになっています(例)。

var xhr = new XMLHttpRequest(),
    fd = new FormData();

fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );

ここで input<input type="file"> フィールドと handler はAjax-requestのsuccess-handlerです。

これは、すべてのブラウザで美しく動作します(繰り返しますが、IEを除く)。

さて、この機能をjQueryで動作させたいと思います。試してみたのがこれ。

var fd = new FormData();    
fd.append( 'file', input.files[0] );

$.post( 'http://example.com/script.php', fd, handler );

残念ながら、これはうまくいきません("Illegal invocation"エラーが投げられます -)。 スクリーンショットはこちら ). jQueryはフォームフィールド名/値を表す単純なkey-valueオブジェクトを期待しているのだと思います。 FormData のインスタンスを渡しているのですが、どうやら互換性がないようです。

さて、このように FormData インスタンスに xhr.send() jQueryで動作させることも可能であればと思います。


更新しました。

jQuery's Bug Trackerにquot;feature ticket"を作成しました。それはここです。 http://bugs.jquery.com/ticket/9995

Ajaxプリフィルタの使用を提案されたのですが...。


更新しました。

まず、どのような動作をさせたいのか、デモをお見せしましょう。

HTMLです。

<form>
    <input type="file" id="file" name="file">
    <input type="submit">
</form>

JavaScriptです。

$( 'form' ).submit(function ( e ) {
    var data, xhr;

    data = new FormData();
    data.append( 'file', $( '#file' )[0].files[0] );

    xhr = new XMLHttpRequest();

    xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
    xhr.onreadystatechange = function ( response ) {};
    xhr.send( data );

    e.preventDefault();
});

上記のコードを実行すると、次のようなHTTP-requestが生成されます。

これは私が必要とするものです - multipart/form-data"のcontent-typeが欲しいです!


解決案としては、このようになります。

$( 'form' ).submit(function ( e ) {
    var data;

    data = new FormData();
    data.append( 'file', $( '#file' )[0].files[0] );

    $.ajax({
        url: 'http://hacheck.tel.fer.hr/xml.pl',
        data: data,
        processData: false,
        type: 'POST',
        success: function ( data ) {
            alert( data );
        }
    });

    e.preventDefault();
});

しかし、この結果

見ての通り、コンテンツタイプがおかしい...。

解決方法は?

このようにできると思います。

var fd = new FormData();    
fd.append( 'file', input.files[0] );

$.ajax({
  url: 'http://example.com/script.php',
  data: fd,
  processData: false,
  contentType: false,
  type: 'POST',
  success: function(data){
    alert(data);
  }
});

注意事項

  • 設定 processData から false を使用すると、jQuery がデータを自動的にクエリ文字列に変換するのを防ぐことができます。参照 ドキュメント をご覧ください。

  • 設定する contentType から false は必須であり、そうでなければ jQuery は正しく設定されません。 .