Safari 11.1: ajax/X입력[type=file]이(가) 비어 있으면 HR 양식 제출이 실패함
업데이트: Webkit 빌드 r230963 현재 이 문제는 Webkit에서 해결되었습니다.
===========
MacOS 및 iOS 및 Safari Technology Preview 11.2의 최신 Safari 11.1 업데이트 이후$.ajax
웹 어플리케이션의 콜이 실패했을 때input[type=file]
선택한 파일이 없습니다(내 양식에는 필요 없음).필드에 파일이 선택되어 있는 경우 오류는 발생하지 않습니다.
그error
의 콜백.ajax
가 실행되고 Safari 콘솔에 다음 메시지가 표시됩니다.Failed to load resource: The operation couldn’t be completed. Protocol error
저는 HTTPS이며, HTTPS를 통해서도 같은 도메인(및 서버)상의 로케이션에 송신하고 있습니다.
11.1 업데이트 전에$.ajax
파일이 선택되지 않은 경우 콜이 정상적으로 전송되었습니다.Chrome과 Firefox의 최신 버전에는 문제가 없습니다.
코드의 관련 부분:
입력:
Browse... <input id="file-upload" type="file" name="image" accept=".jpg,.jpeg">
JS:
var formData = new FormData($(this)[0]);
$.ajax({
type: 'POST',
enctype: 'multipart/form-data',
url: '../process.php',
data: formData,
contentType: false,
processData: false,
cache: false,
success: function(response) { ... },
error: function() { //my code reaches here }
});
임시(바람직한) 솔루션으로서 빈 파일필드를 검출하여 에서 삭제합니다.formData
이 되기 전에ajax
모든 것이 예상대로/전에는 정상적으로 동작합니다.
$("input[type=file]").each(function() {
if($(this).val() === "") {
formData.delete($(this).attr("name"));
}
});
제가 잘못하고 있는 건가요, Safari에 문제가 있나요, 아니면 Safari에서 현재 해결해야 할 변경 사항이 있나요?
업데이트: Firefox에서는 오래된 답변이 작동하지 않습니다.
Firefox가 빈 문자열만 반환하는 경우FormData.get()
(다른 브라우저의 File 객체가 아닌) 빈 파일 필드에 있습니다.따라서 이전 회피책을 사용할 때는 비어 있습니다.<input type="file">
비어 있는 것처럼 보내집니다.<input type="text">
유감스럽게도 FormData 객체를 작성한 후에는 빈 파일과 빈 텍스트를 구분할 수 없습니다.
대신 다음 솔루션을 사용하십시오.
var $form = $('form')
var $inputs = $('input[type="file"]:not([disabled])', $form)
$inputs.each(function(_, input) {
if (input.files.length > 0) return
$(input).prop('disabled', true)
})
var formData = new FormData($form[0])
$inputs.prop('disabled', false)
라이브 데모: https://jsfiddle.net/ypresto/05Lc45eL/
jQuery 이외의 환경의 경우:
var form = document.querySelector('form')
var inputs = form.querySelectorAll('input[type="file"]:not([disabled])')
inputs.forEach(function(input) {
if (input.files.length > 0) return
input.setAttribute('disabled', '')
})
var formData = new FormData(form)
inputs.forEach(function(input) {
input.removeAttribute('disabled')
})
레일(레일-ujs/j)의 경우Query-ujs):https://gist.github.com/ypresto/cabce63b1f4ab57247e1f836668a00a5
오래된 답변:
FormData 필터링(Ravichandra Adiga의 답변)은 DOM을 조작하지 않기 때문에 더 좋습니다.
그러나 FormData의 부품 순서는 폼에서 요소를 입력하는 순서와 동일함을 보증합니다.<form>
사양.이 사양에 의존하는 경우 다른 버그가 발생할 수 있습니다.
다음 스니펫은 Form Data 순서와 빈 부분을 유지합니다.
var formDataFilter = function(formData) {
// Replace empty File with empty Blob.
if (!(formData instanceof window.FormData)) return
if (!formData.keys) return // unsupported browser
var newFormData = new window.FormData()
Array.from(formData.entries()).forEach(function(entry) {
var value = entry[1]
if (value instanceof window.File && value.name === '' && value.size === 0) {
newFormData.append(entry[0], new window.Blob(), '')
} else {
newFormData.append(entry[0], value)
}
})
return newFormData
}
라이브의 예는, https://jsfiddle.net/ypresto/y6v333bq/ 입니다.
Rails에 대해서는, https://github.com/rails/rails/issues/32440#issuecomment-381185380 를 참조해 주세요.
(메모: iOS 11.3의 Safari에서는 이 문제가 발생하지만 11.2에서는 발생하지 않습니다.)
회피책으로 jQuery remove() 메서드를 사용하여 입력 유형 파일을 DOM에서 완전히 삭제합니다.
$("input[type=file]").each(function() {
if($(this).val() === "") {
$(this).remove();
}
});
Webkit 빌드 r230963 현재 이 문제는 Webkit에서 해결되었습니다.그 빌드를 다운로드하여 실행한 결과 문제가 해결되었음을 확인했습니다.이 수정 프로그램이 포함된 Safari의 공개 릴리스가 언제 제공될지는 알 수 없습니다.
Perl 프로그램에서 동일한 문제로 보이는 작업을 수행했습니다.
Perl에서 멀티파트/폼 데이터를 처리하면 폼 파일 요소가 비어 있는 경우 Apple 디바이스에서 Apache 오류가 발생합니다.
회피책은 폼 데이터를 할당하기 전에 폼 요소를 삭제하는 것입니다.
$('#myForm').find("input[type='file']").each(function(){
if ($(this).get(0).files.length === 0) {$(this).remove();}
});
var fData = new FormData($('#myForm')[0]);
...
var fileNames = formData.getAll("filename[]");
formData.delete("filename[]");
jQuery.each(fileNames, function (key, fileNameObject) {
if (fileNameObject.name) {
formData.append("filename[]", fileNameObject);
}
});
이거 먹어봐!!
입력 필드가 비어 있는지 확인할 수 있습니다.비어 있는 경우 FormData를 작성하기 전에 입력 필드를 비활성화합니다.FormData를 작성한 후 "disabled" 속성을 삭제합니다.다른 답변과 다른 점은 "input[0]"을 검색한다는 것입니다.files.length == 0" 입니다.
// get the input field with type="file"
var input = $('#myForm').find("input[type='file']")
// add the "disabled" attribute to the input
if (input[0].files.length == 0) {
input.prop('disabled', true);
}
// create the formdata
var formData = new FormData($(this)[0]);
// remove the "disabled" attribute
input.prop('disabled', false);
언급URL : https://stackoverflow.com/questions/49614091/safari-11-1-ajax-xhr-form-submission-fails-when-inputtype-file-is-empty
'source' 카테고리의 다른 글
사이트를 설치할 수 없습니다. 일치하는 서비스 작업자가 검색되지 않았습니다. (0) | 2023.03.20 |
---|---|
경고:목록의 각 아이는 고유한 "키" 소품을 가지고 있어야 합니다. (0) | 2023.03.20 |
React.useMemo를 사용한 비동기 호출 (0) | 2023.03.20 |
워드프레스:기본 메뉴 항목에 URL GET 매개 변수를 추가하려면 어떻게 해야 합니까? (0) | 2023.03.20 |
문자열이 유효한 JSON인지 확인하는 방법 (0) | 2023.03.20 |