如何指定multipart/form-data请求边界?自定义边界被自动替换问题
解决AngularJS $resource上传FormData时边界被替换的问题
我之前也碰到过这个坑,其实这不是bug,是浏览器和AngularJS的默认行为在起作用——当你用FormData上传文件时,浏览器会自动生成唯一的WebKitFormBoundary作为分隔边界,你手动设置的边界会被直接忽略,这是为了避免自定义边界和请求内容里的字符串重复,导致服务器解析出错。
下面是具体的解决步骤和代码调整方案:
1. 修正$resource的配置
你需要修改save方法的配置,让AngularJS不要序列化FormData,同时不要手动指定Content-Type,交给浏览器自动处理:
.factory('FilesPaymentsImportationsUploadResource', function ($resource, PAYMENTS_API_URL) { return $resource(PAYMENTS_API_URL + '/v1/payment-files/upload/', { id: "@id" }, { save: { method: 'POST', // 关键:跳过AngularJS默认的序列化,直接传递FormData给浏览器 transformRequest: angular.identity, // 让浏览器自动设置Content-Type(包含正确的随机边界) headers: { 'Content-Type': undefined } } }); })
2. 正确构建请求体
使用原生FormData对象来组装上传的文件,不要手动拼接form-data内容:
// 假设你已经获取到了文件对象(比如从<input type="file">里拿到的) const uploadFormData = new FormData(); uploadFormData.append('file', yourFileObject); // 如果需要额外参数,直接append即可 uploadFormData.append('extra_param', 'some_value'); // 调用resource的save方法 FilesPaymentsImportationsUploadResource.save(uploadFormData);
为什么这么做?
- AngularJS默认的
transformRequest会尝试把请求数据序列化为JSON,但FormData是浏览器原生的表单数据对象,不需要序列化。用angular.identity可以跳过这个过程,直接把FormData交给XMLHttpRequest处理。 - 当你把
Content-Type设为undefined时,浏览器会自动检测到你传递的是FormData,自动添加multipart/form-data头,并生成唯一的边界字符串,这个边界是服务器能正常解析的,完全不用担心兼容性问题。
内容的提问来源于stack exchange,提问作者TheNameless
相关产品推荐
相关产品推荐

