[jquery] jQuery.ajax로 멀티 파트 / 폼 데이터 보내기

jQuery의 ajax 함수를 사용하여 파일을 서버 측 PHP 스크립트로 보내는 데 문제가 있습니다. 파일 목록을 가져올 수는 $('#fileinput').attr('files')있지만이 데이터를 서버로 보내는 방법은 무엇입니까? 파일 입력을 사용할 때 $_POST서버 측 php-script 의 결과 배열 ( )은 0 ( NULL)입니다.

가능하다는 것을 알고 있습니다 (지금까지는 jQuery 솔루션을 찾지 못했지만 프로토 코드 만 ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) ).

이것은 비교적 새로운 것으로 보이므로 XHR / Ajax를 통한 파일 업로드는 불가능할 것입니다.

Safari 5의 기능이 필요합니다 .FF 및 Chrome은 훌륭하지만 필수는 아닙니다.

지금 내 코드는 다음과 같습니다

$.ajax({
    url: 'php/upload.php',
    data: $('#file').attr('files'),
    cache: false,
    contentType: 'multipart/form-data',
    processData: false,
    type: 'POST',
    success: function(data){
        alert(data);
    }
});



답변

Safari 5 / Firefox 4부터는 FormData클래스 를 사용하는 것이 가장 쉽습니다 .

var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file-'+i, file);
});

이제 FormDataXMLHttpRequest와 함께 보낼 준비 가 된 객체가 있습니다.

jQuery.ajax({
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
});

jQuery가 헤더 를 추가하지 않도록 contentType옵션을 설정해야 합니다. 그렇지 않으면 경계 문자열이 누락됩니다. 또한 플래그를 false로 설정 해야합니다 . 그렇지 않으면 jQuery가 문자열을 문자열 로 변환하려고 시도하므로 실패합니다.falseContent-TypeprocessDataFormData

다음을 사용하여 PHP에서 파일을 검색 할 수 있습니다.

$_FILES['file-0']

( 파일 입력에 속성을 file-0지정하지 않으면 파일 하나만 있습니다.이 multiple경우 각 파일마다 숫자가 증가합니다.)

이전 브라우저에 FormData 에뮬레이션 사용

var opts = {
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
};
if(data.fake) {
    // Make sure no text encoding stuff is done by xhr
    opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
    opts.contentType = "multipart/form-data; boundary="+data.boundary;
    opts.data = data.toString();
}
jQuery.ajax(opts);

기존 양식에서 FormData 작성

파일을 수동으로 반복하는 대신 기존 양식 객체의 내용으로 FormData 객체를 만들 수도 있습니다.

var data = new FormData(jQuery('form')[0]);

카운터 대신 PHP 기본 배열을 사용하십시오.

파일 요소 이름을 동일하게 지정하고 이름을 대괄호로 끝내십시오.

jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file[]', file);
});

$_FILES['file']그러면 업로드 된 모든 파일의 파일 업로드 필드가 포함 된 배열이됩니다. 실제로 반복하는 것이 더 간단하므로 초기 솔루션보다 이것을 권장합니다.


답변

라파엘의 위대한 답변에 약간을 추가하고 싶었습니다. $_FILESJavaScript를 사용하여 제출하는지 여부에 관계없이 PHP가 동일한 것을 생성하도록하는 방법은 다음과 같습니다 .

HTML 양식 :

<form enctype="multipart/form-data" action="/test.php"
method="post" class="putImages">
   <input name="media[]" type="file" multiple/>
   <input class="button" type="submit" alt="Upload" value="Upload" />
</form>

$_FILESJavaScript없이 제출하면 PHP는 이것을 생성합니다 .

Array
(
    [media] => Array
        (
            [name] => Array
                (
                    [0] => Galata_Tower.jpg
                    [1] => 518f.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpIQaOYo
                    [1] => /tmp/phpJQaOYo
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 258004
                    [1] => 127884
                )

        )

)

점진적 향상을 수행하는 경우 Raphael의 JS를 사용하여 파일을 제출하십시오.

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

$.ajax({
    type: ppiFormMethod,
    data: data,
    url: ppiFormActionURL,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data){
        alert(data);
    }
});

…이 $_FILESJavaScript를 사용하여 제출 한 후 PHP의 배열은 다음과 같습니다.

Array
(
    [0] => Array
        (
            [name] => Galata_Tower.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpAQaOYo
            [error] => 0
            [size] => 258004
        )

    [1] => Array
        (
            [name] => 518f.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpBQaOYo
            [error] => 0
            [size] => 127884
        )

)

멋진 배열이며 실제로 일부 사람들이 변형 $_FILES하는 것이지만 $_FILESJavaScript를 사용하여 제출하는 데 관계없이 동일하게 작업하는 것이 유용하다는 것을 알았습니다 . JS에 약간의 변화가 있습니다 :

// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );

// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
    data.append(fileInputName+'['+i+']', file);
});

(2017 년 4 월 14 일 편집 : FormData () 생성자에서 양식 요소를 제거했습니다.이 코드는 Safari에서 수정되었습니다.)

그 코드는 두 가지 일을합니다.

  1. inputname 속성을 자동으로 검색하여 HTML을 유지 관리하기 쉽게 만듭니다. 이제 formputImages 클래스가 있으면 다른 모든 것이 자동으로 처리됩니다. 즉, input특별한 이름이 필요하지 않습니다.
  2. 일반 HTML이 제출하는 배열 형식은 data.append 행의 JavaScript에 의해 다시 작성됩니다. 괄호에 유의하십시오.

이러한 변경으로 이제 JavaScript $_FILES로 제출하면 간단한 HTML로 제출 하는 것과 정확히 동일한 배열이 생성 됩니다.


답변

내 코드를 봐, 그것은 나를 위해 일을

$( '#formId' )
  .submit( function( e ) {
    $.ajax( {
      url: 'FormSubmitUrl',
      type: 'POST',
      data: new FormData( this ),
      processData: false,
      contentType: false
    } );
    e.preventDefault();
  } );


답변

방금 읽은 정보를 기반 으로이 기능을 만들었습니다.

.serialize()대신 사용하여 사용하십시오 .serializefiles();.
내 테스트에서 일하고 있습니다.

//USAGE: $("#form").serializefiles();
(function($) {
$.fn.serializefiles = function() {
    var obj = $(this);
    /* ADD FILE TO PARAM AJAX */
    var formData = new FormData();
    $.each($(obj).find("input[type='file']"), function(i, tag) {
        $.each($(tag)[0].files, function(i, file) {
            formData.append(tag.name, file);
        });
    });
    var params = $(obj).serializeArray();
    $.each(params, function (i, val) {
        formData.append(val.name, val.value);
    });
    return formData;
};
})(jQuery);


답변

양식이 HTML에 정의되어 있으면 양식을 반복하고 이미지를 추가하는 것보다 생성자로 전달하는 것이 더 쉽습니다.

$('#my-form').submit( function(e) {
    e.preventDefault();

    var data = new FormData(this); // <-- 'this' is your form element

    $.ajax({
            url: '/my_URL/',
            data: data,
            cache: false,
            contentType: false,
            processData: false,
            type: 'POST',
            success: function(data){
            ...


답변

Devin Venable의 대답 은 내가 원하는 것과 비슷했지만 여러 양식에서 작동하는 양식을 원했고 양식에 이미 지정된 작업을 사용하여 각 파일이 올바른 위치로 이동했습니다.

또한 jQuery의 on () 메소드를 사용하여 .ready () 사용을 피할 수있었습니다.

그것은 나를 알게되었습니다 : (formSelector를 jQuery 선택기로 대체하십시오)

$(document).on('submit', formSelecter, function( e ) {
        e.preventDefault();
    $.ajax( {
        url: $(this).attr('action'),
        type: 'POST',
        data: new FormData( this ),
        processData: false,
        contentType: false
    }).done(function( data ) {
        //do stuff with the data you got back.
    });

});


답변

요즘에는 jQuery가 필요하지 않습니다 🙂 API 지원 테이블 가져 오기

let result = fetch('url', {method: 'POST', body: new FormData(document.querySelector("#form"))})