业务背景: 服务器后端生成签名给前端; 前端通过 http 只接上传文件;这样不需要使用SDK 即可完成上传到 阿里云OSS, 这里使用的是 :PostObjecthttps://help.aliyun.com/document_detail/31988.html
遇到的问题 :应为是 Flutter 应用这边使用的网络库是:http,上传的时候一直报:
代码如下:
Future<ResponseBase> upLoadImage( {required String policy, required String signature, required String dir, required String fileName, required String filePath}) async { try { AppOverlay().showLoading(title: '正在上传...'); Uri url = Uri.http('xxooxxoo.oss-cn-hangzhou.aliyuncs.com', ''); MultipartRequest request = MultipartRequest('POST', url); request.fields['policy'] = policy; request.fields['signature'] = signature; request.fields['OSSAccessKeyId'] = 'LTAI5tKHpGbunzBrasdasdW';//换成自己的 request.fields['key'] = '$dir/$fileName'; http.MultipartFile multipartFile = await http.MultipartFile.fromPath("file", filePath); request.files.add(multipartFile); http.StreamedResponse response = await request.send(); if (response.statusCode == 204) { //这里返回值用到了Stream回调 ResponseBase _responseBase = ResponseBase( success: true, entityList: null, messageID: 0, content: '上传成功', ); return _responseBase; } else { AppScreen.showToast('上传文件失败 请稍后再试 code:${response.statusCode}'); return ResponseBase( messageID: response.statusCode, success: false, content: '上传文件失败 请稍后再试 ${response.statusCode}', entityList: '', ); } } catch (exception) { AppScreen.showToast('上传文件失败 请稍后再试 ${exception.toString()}'); // return ResponseBase( // errorCode: -100, // action: 0, // message: '网络异常 请稍后再试 -100', // success: false, // value: {'error get': exception.toString()}, // ); return ResponseBase( messageID: -100, success: false, content: '网络异常 请稍后再试 -100', entityList: '', ); } finally { AppOverlay().hideLoading(); } }报错信息
"The body of your POST request is not well-formed multipart/form-data"
<Error> <Code>MalformedPOSTRequest</Code> <Message>The body of your POST request is not well-formed multipart/form-data</Message> <RequestId>636C62D5FDF07836388721F1</RequestId> <HostId>pingchuang.oss-cn-hangzhou.aliyuncs.com</HostId> </Error>填坑发现:
flutter 'content-type' 字段在 'content-disposition' 字段的上面;然而 阿里云OSS 要求 : 'content-type' 字段在 'content-disposition' 字段的下面;
好嘛 事已至此我们只能修改源文件了 MultipartRequest
找到 MultipartRequest.dart ,
在这里大家最好复制一份出来; 不要在源文件上面修改!
找到这个方法,修改成下面的样子:
实际上就是 换了下位置!
/// Returns the header string for a file. /// /// The return value is guaranteed to contain only ASCII characters. String _headerForFile(MultipartFile file) { // var header = 'content-type: ${file.contentType}\r\n' // 'content-disposition: form-data; name="${_browserEncode(file.field)}"'; // // if (file.filename != null) { // header = '$header; filename="${_browserEncode(file.filename!)}"'; // } // return '$header\r\n\r\n'; var header = ''; if (file.filename != null) { header = 'content-disposition: form-data; name="${_browserEncode(file.field)}"; filename="${_browserEncode(file.filename!)}"\r\n' 'content-type: ${file.contentType}'; } else { header = 'content-disposition: form-data; name="${_browserEncode(file.field)}"\r\n' 'content-type: ${file.contentType}'; } return '$header\r\n\r\n'; }
换完成功我门再试下:
成功返回 204 说明是成功了!