Mat*_*tt. 38 javascript forms safari ajax jquery
更新:从Webkit build r230963开始,此问题已在Webkit中得到解决.
===========
自从最近在macOS和iOS上以及Safari Technology Preview 11.2中进行Safari 11.1更新以来,$.ajax当一个input[type=file]字段没有选择文件时(我的表单中不需要),我的Web应用程序中的调用失败.当字段确实选择了文件时没有失败.
该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">
Run Code Online (Sandbox Code Playgroud)
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 }
});
Run Code Online (Sandbox Code Playgroud)
作为一个临时的(希望)解决方案,我正在检测一个空文件字段并formData在ajax调用之前删除它,一切都按预期/之前工作:
$("input[type=file]").each(function() {
if($(this).val() === "") {
formData.delete($(this).attr("name"));
}
});
Run Code Online (Sandbox Code Playgroud)
我做错了什么,Safari是否存在问题,或者现在在ajax调用中是否需要考虑Safari的变化?
ypr*_*sto 18
更新:旧答案在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)
Run Code Online (Sandbox Code Playgroud)
现场演示: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')
})
Run Code Online (Sandbox Code Playgroud)
对于Rails(rails-ujs/jQuery-ujs):https://gist.github.com/ypresto/cabce63b1f4ab57247e1f836668a00a5
旧答案:
过滤FormData(在Ravichandra Adiga的回答中)更好,因为它不会操纵任何DOM.
但是,根据规范,FormData中的部件顺序保证与输入表单中的元素顺序相同<form>.如果有人依赖此规范,它可能会导致另一个错误.
片段下方将保留FormData顺序和空白部分.
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
}
Run Code Online (Sandbox Code Playgroud)
现场示例如下: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();
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9940 次 |
| 最近记录: |