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);
});
이제 FormData
XMLHttpRequest와 함께 전송 될 객체가 준비되었습니다.
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가 문자열을 문자열 로 변환하려고 시도하므로 실패합니다.false
Content-Type
processData
FormData
이제 다음을 사용하여 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']
그러면 업로드 된 모든 파일의 파일 업로드 필드가 포함 된 배열이됩니다. 실제로 반복하는 것이 더 간단하므로 초기 솔루션보다 이것을 권장합니다.
라파엘의 위대한 답변에 약간을 추가하고 싶었습니다. $_FILES
JavaScript를 사용하여 제출하는지 여부에 관계없이 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>
$_FILES
JavaScript없이 제출하면 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);
}
});
...이 $_FILES
JavaScript를 사용하여 제출 한 후 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
하는 것이지만 $_FILES
JavaScript를 사용하여 제출하는 데 관계없이 동일한 작업을 수행하는 것이 유용하다는 것을 알았습니다 . 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에서 수정되었습니다.)
그 코드는 두 가지 일을합니다.
input
name 속성을 자동으로 검색하여 HTML을 유지 관리하기 쉽게 만듭니다. 이제form
putImages 클래스가 있으면 다른 모든 것이 자동으로 처리됩니다. 즉,input
특별한 이름이 필요하지 않습니다.- 일반 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.
});
});
FormData 클래스는 작동하지만 iOS Safari (iPhone 이상)에서는 Raphael Schweikert의 솔루션을 그대로 사용할 수 없었습니다.
Mozilla Dev에는 FormData 객체 조작에 대한 유용한 페이지 가 있습니다 .
따라서 enctype을 지정하여 페이지 어딘가에 빈 양식을 추가하십시오.
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>
그런 다음 FormData 오브젝트를 다음과 같이 작성하십시오.
var data = new FormData($("#fileinfo"));
Raphael의 코드 에서와 같이 진행하십시오 .
오늘 내가 겪었던 한 가지 문제는이 문제와 관련하여 지적 할 가치가 있다고 생각합니다 .ajax 호출의 URL이 리디렉션되면 content-type : 'multipart / form-data'의 헤더가 손실 될 수 있습니다.
예를 들어 http://server.com/context?param=x 에 게시하고있었습니다 .
Chrome의 네트워크 탭 에서이 요청에 대한 올바른 멀티 파트 헤더를 보았지만 302가 http://server.com/context/?param=x로 리디렉션되었습니다 (컨텍스트 후 슬래시 참고)
리디렉션하는 동안 멀티 파트 헤더가 손실되었습니다. 이러한 솔루션이 작동하지 않으면 요청이 리디렉션되지 않도록하십시오.
위의 모든 솔루션은 훌륭하고 우아해 보이지만 FormData () 객체는 매개 변수를 기대하지 않지만 인스턴스화 후 append ()를 사용하여 위와 같이 작성합니다.
formData.append (val.name, val.value);
요즘에는 jQuery가 필요하지 않습니다 :) API 지원 테이블 가져 오기
let result = fetch('url', {method: 'POST', body: new FormData(document.querySelector("#form"))})
이전 버전의 IE는 FormData를 지원하지 않습니다 (FormData에 대한 전체 브라우저 지원 목록은 https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
jquery 플러그인 (예 : http://malsup.com/jquery/form/#code-samples )을 사용하거나 IFrame 기반 솔루션을 사용하여 ajax를 통해 멀티 파트 양식 데이터를 게시 할 수 있습니다 ( https : // developer). mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
파일 입력하면 name
배열 및 플래그를 표시 multiple
하고 전체를 구문 분석 form
과 함께 FormData
, 그것은 반복 할 필요가 없습니다 append()
입력 파일. FormData
여러 파일을 자동으로 처리합니다.
$('#submit_1').on('click', function() {
let data = new FormData($("#my_form")[0]);
$.ajax({
url: '/path/to/php_file',
type: 'POST',
data: data,
processData: false,
contentType: false,
success: function(r) {
console.log('success', r);
},
error: function(r) {
console.log('error', r);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="my_form">
<input type="file" name="multi_img_file[]" id="multi_img_file" accept=".gif,.jpg,.jpeg,.png,.svg" multiple="multiple" />
<button type="button" name="submit_1" id="submit_1">Not type='submit'</button>
</form>
이 아닌 일반 button type="button"
이 사용됩니다 type="submit"
. 이것은 submit
이 기능을 얻기 위해 사용하는 데 의존성이 없음을 나타냅니다 .
결과 $_FILES
항목은 Chrome 개발 도구에서 다음과 같습니다.
multi_img_file:
error: (2) [0, 0]
name: (2) ["pic1.jpg", "pic2.jpg"]
size: (2) [1978036, 2446180]
tmp_name: (2) ["/tmp/phphnrdPz", "/tmp/phpBrGSZN"]
type: (2) ["image/jpeg", "image/jpeg"]
참고 : 단일 파일로 업로드 할 때 일부 이미지가 제대로 업로드되는 경우가 있지만 여러 파일 세트로 업로드하면 이미지가 실패하는 경우가 있습니다. 증상은 PHP가 비어 $_POST
있고 $_FILES
AJAX가 오류를 발생시키지 않고 보고한다는 것 입니다. Chrome 75.0.3770.100 및 PHP 7.0에서 문제가 발생합니다. 내 테스트 세트에서 수십 개의 이미지 중 하나에서만 발생하는 것 같습니다.
- jquery-> $ ( "# id") [0]에 의해 폼 객체를 얻는다
- data = 새 FormData ($ ( "# id") [0]);
- 좋아, 데이터는 네가 원해
참고 URL : https://stackoverflow.com/questions/5392344/sending-multipart-formdata-with-jquery-ajax
'development' 카테고리의 다른 글
브라우저가 CSS 선택기를 오른쪽에서 왼쪽으로 일치시키는 이유는 무엇입니까? (0) | 2020.02.10 |
---|---|
파이썬에서 환경 변수를 설정하는 방법 (0) | 2020.02.10 |
"매개 변수"vs "인수" (0) | 2020.02.10 |
파이썬에서 자식 클래스에서 부모 클래스의 메소드를 호출 하시겠습니까? (0) | 2020.02.10 |
공백 문자가있는 문자열을 구분 기호로 어떻게 분할합니까? (0) | 2020.02.10 |