Jak wysyłać Obiekty FormData za pomocą Ajax-requests w jQuery? [duplikat]

To pytanie ma już odpowiedź tutaj:

XMLHttpRequest Poziom 2 standard (nadal roboczy szkic) definiuje interfejs FormData. Interfejs ten umożliwia dołączanie obiektów File do XHR-requests (Ajax-requests).

Btw, to jest nowa funkcja - w w przeszłości użyto "hidden-iframe-trick"(przeczytaj o tym w Moje inne pytanie).

Tak to działa (przykład):

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 );

Gdzie input jest polem <input type="file">, a handler jest Obsługą sukcesu dla żądania Ajax.

To działa pięknie we wszystkich przeglądarkach (znowu, z wyjątkiem IE).

Teraz chciałbym, aby ta funkcjonalność działała z jQuery. Próbowałem tego:

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

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

Niestety, to nie zadziała (błąd" nielegalnego wywołania " jest wyrzucany - zrzut ekranu jest tutaj ). Zakładam, że jQuery oczekuje prostego obiektu klucz-wartość reprezentującego form-field-names / values, a instancja FormData, którą przekazuję, jest najwyraźniej niezgodna.

Teraz, ponieważ możliwe jest przekazanie instancji FormData do xhr.send(), mam nadzieję, że jest również możliwe, aby działała z jQuery.


Update:

Stworzyłem "feature ticket" w jQuery ' s Bug Tracker. Jest tutaj.: http://bugs.jquery.com/ticket/9995

Zaproponowano mi użycie "Ajax prefilter"...


Update:

Po pierwsze, pozwól mi dać demo demonstrujące jakie zachowanie chciałbym osiągnąć.

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();
});

Powyższy kod powoduje to HTTP-request:

multipartformdata

To jest to, czego potrzebuję - chcę tego typu treści "multipart / form-data"!


The proponowane rozwiązanie byłoby takie:

$( '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();
});

Jednak to daje:

wrongcontenttype

Jak widać, typ treści jest zły...

Author: Community, 2011-08-07

10 answers

Wierzę, że można to zrobić tak:

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);
  }
});

Ustawienie processData Na false pozwala zapobiec automatycznemu przekształcaniu danych przez jQuery w ciąg zapytania. Zobacz docs aby uzyskać więcej informacji.

Ustawienie contentType Na false jest konieczne, ponieważ w przeciwnym razie jQuery ustawi je nieprawidłowo .

 719
Author: pradeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 20:44:49

Istnieje kilka jeszcze wymienionych technik dostępnych dla Ciebie. Zacznij od ustawienia właściwości contentType w params ajax.

Na przykładzie pradeeka:

$('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',

        // This will override the content type header, 
        // regardless of whether content is actually sent.
        // Defaults to 'application/x-www-form-urlencoded'
        contentType: 'multipart/form-data', 

        //Before 1.5.1 you had to do this:
        beforeSend: function (x) {
            if (x && x.overrideMimeType) {
                x.overrideMimeType("multipart/form-data");
            }
        },
        // Now you should be able to do this:
        mimeType: 'multipart/form-data',    //Property added in 1.5.1

        success: function (data) {
            alert(data);
        }
    });

    e.preventDefault();
});

W niektórych przypadkach zmuszając jQuery ajax do robienia rzeczy nie oczekiwanych, Zdarzenie beforeSend jest doskonałym miejscem do tego. Przez jakiś czas ludzie używali beforeSend do nadpisywania typu MIME zanim został dodany do jQuery w 1.5.1. Powinieneś być w stanie zmodyfikować prawie wszystko na obiekcie jqXHR w przed wyślij wydarzenie.

 25
Author: BenSwayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-30 00:20:43

Możesz wysłać obiekt FormData w żądaniu ajax używając następującego kodu,

$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
});

Jest to bardzo podobne do zaakceptowanej odpowiedzi, ale rzeczywista odpowiedź na temat pytania. Spowoduje to wysłanie elementów formularza automatycznie do FormData i nie ma potrzeby ręcznego dołączania danych do zmiennej FormData.

Metoda ajax wygląda tak,

$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
    //append some non-form data also
    formData.append('other_data',$("#someInputData").val());
    $.ajax({
        type: "POST",
        url: postDataUrl,
        data: formData,
        processData: false,
        contentType: false,
        dataType: "json",
        success: function(data, textStatus, jqXHR) {
           //process data
        },
        error: function(data, textStatus, jqXHR) {
           //process error msg
        },
});

Można również ręcznie przekazać element formularza wewnątrz obiektu FormData jako parametr this

var formElem = $("#formId");
var formdata = new FormData(form[0]);
Mam nadzieję, że to pomoże. ;)
 12
Author: Lucky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-28 22:00:23

Możesz użyć $.Zdarzenie ajax beforeSend do manipulowania nagłówkiem.

beforeSend: function(xhr) { 
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}

Zobacz ten link, aby uzyskać dodatkowe informacje: http://msdn.microsoft.com/en-us/library/ms536752 (v=vs.85). aspx

 5
Author: dmnkhhn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-28 21:12:35

Myślę, że nie można to zrobić w ajax do obsługi wszystkich przeglądarek, mogę powiedzieć, dobrze sprawdzić ten Ajax uploader plugin, aby zobaczyć, jak to zrobili http://valums.com/ajax-upload/

 4
Author: nivanka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 09:18:30

Robię to tak i to działa dla mnie, mam nadzieję, że to pomoże:)

   <div id="data">
        <form>
            <input type="file" name="userfile" id="userfile" size="20" />
            <br /><br />
            <input type="button" id="upload" value="upload" />
        </form>
    </div>
  <script>
        $(document).ready(function(){
                $('#upload').click(function(){

                    console.log('upload button clicked!')
                    var fd = new FormData();    
                    fd.append( 'userfile', $('#userfile')[0].files[0]);

                    $.ajax({
                      url: 'upload/do_upload',
                      data: fd,
                      processData: false,
                      contentType: false,
                      type: 'POST',
                      success: function(data){
                        console.log('upload success!')
                        $('#data').empty();
                        $('#data').append(data);

                      }
                    });
                });
        });
    </script>   
 4
Author: talalalshehri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-28 15:17:47

Jeśli chcesz przesłać pliki za pomocą ajax użyj "jquery.forma.js" To łatwo przesyła wszystkie elementy formularza.

Próbki http://jquery.malsup.com/form/#ajaxSubmit

Rough view:

<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>


<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{ 
    information= responseText;
    callAjaxtolist();
    $("#AddPhotoForm").resetForm();
    $("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');        
};

$(document).ready(function(){
    $('.add_new_photo_div').live('click',function(){
            var options = {success:showResponseAfterAddPhoto};  
            $("#AddPhotoForm").ajaxSubmit(options);
        });
});
</script>
 2
Author: Rohit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-30 14:43:20

JavaScript:

 function submitForm() {
                var data1 = new FormData($('input[name^="file"]'));
                $.each($('input[name^="file"]')[0].files, function(i, file) {
                data1.append(i, file);
                });

    $.ajax({
      url: "<?php echo base_url() ?>employee/dashboard2/test2",
      type: "POST",
      data: data1,
      enctype: 'multipart/form-data',
      processData: false,  // tell jQuery not to process the data
      contentType: false   // tell jQuery not to set contentType
    }).done(function(data) {
        console.log("PHP Output:");
        console.log( data );
    });
    return false;
}

PHP:

public function upload_file(){

    foreach ($_FILES as $key ) {

          $name =time().$key['name'];

          $path='upload/'.$name;

          @move_uploaded_file($key['tmp_name'],$path);

    }
 2
Author: Rahul Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 10:32:03

Zamiast- fd.append( 'userfile', $('#userfile')[0].files[0]);

Użyj - fd.append( 'file', $('#userfile')[0].files[0]);

 2
Author: user4757231,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 10:40:45

Najlepsza dokumentacja i przykład jaki znalazłem to tutaj https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects

 0
Author: DoodleKana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-14 20:50:42