开发遇坑,用$.ajax
上传文件,后台报错the request was rejected because no multipart,研究发现是$.ajax
里contentType设置有问题,不能直接设置为multipart/form-data
,而需要设为false
,具体看代码:
HTML部分:
<body>
<input type="text" name="id" id="id" value="" />
<input type="text" name="text" id="text" value="" />
<input type="file" multiple="multiple" id="files" name="files">
body>
首先构建需上传的数据对象
var files = $('#files')[0].files;
var imgFiles = [];
for (var i = 0; i < files.length; i++) {
var file = files[i];
//保存文件到数组
imgFiles.push(file);
}
var obj = {
id:$("#id").val(),
text:$("#text").val(),
files:imgFiles
}
将数据对象转换为formData:
var fromData = new FormData();
$.each(obj,function(key,value) {
fromData.append(key,value);
})
最后使用$.ajax提交:
$.ajax({
type: 'post',
url: 'url',
cache: false,
contentType: "multipart/form-data",
processData: false, //默认为true,默认情况下,发送的数据将被转换为对象,设为false不希望进行转换
data: fromData, //数据
success: function(data, textStatus, jqXHR) {
console.log("请求返回success信息data:", data);
}
});
此时后台会报错:the request was rejected because no multipart
F12查看network一栏的请求信息,发现contentType设置成功,但还是会报错:
为什么会报错呢?我们先把$.ajax里的contentType设为false
,再次发送请求:
$.ajax({
type: 'post',
url: 'url',
cache: false,
contentType: false,
processData: false, //默认为true,默认情况下,发送的数据将被转换为对象,设为false不希望进行转换
data: fromData, //数据
success: function(data, textStatus, jqXHR) {
console.log("请求返回success信息data:", data);
}
});
请求成功,查看network的请求信息:
发现成功时比失败时contentType多了一串boundary+一串字符,后面的一堆字符串是随机生成的,目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置。
在 ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。
如果不用$.ajax
,而是使用原生form提交,将form表单的enctype设为"multipart/form-data"也能正常提交到服务器(form的"multipart/form-data"是将文件以二进制的形式上传,这样可以实现多种类型的文件上传)
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="id" id="id" value="" />
<input type="file" multiple="multiple" id="files" name="files">
<input type="submit" value=""/>
form>
$.ajax
发送请求,则需要将配置项contentType设为false
,而不能直接设置为"multipart/form-data",后者发送的请求在Request headers的contentType中没有分界符,会导致后台无法解析并报错。本文参考: