上一篇讲了flutter for web 开发简单实现http post请求的几种方式,感兴趣的读者可以自行查看。
一、Web端如何选择文件
在Flutter中,我们可以使用FileUploadInputElement来打开文件选择器。
InputElement uploadInput = FileUploadInputElement();
比如在按钮被点击的时候要打开文件选择器,只需要调用如下一句。
uploadInput.click();
在此之前,我们需要添加监听器
uploadInput.multiple=true;//支持多文件选择,默认为false
uploadInput.onChange.listen((event) { });//监听器,选择的文件发生变化时调用
该组件有foreach方法遍历file对象
uploadInput.files.forEach((element) {
});
要注意的是,该组件获取到的file对象是html.File类,不能像Flutter做Android或ios开发时那样,直接使用io.File进行文件传输。
准备完了,接下来就是正式工作了。
二、文件上传的实现。
html.File对象可以通过slice方法获取文件的blob,但我们不能直接上传blob类型,因为blob类型只支持使用方法1上传,所以可以用FileReader来读取。
var reader = html.FileReader();
reader.readAsDataUrl(file.slice());
reader.onLoadEnd.listen((event) { //读取结束监听});
1.使用html包实现。
var request = html.HttpRequest();
request.open('method', 'url');
var formdata = html.FormData();
formdata.appendBlob('key', file.slice(), file.name);
request.send(formdata);
2.使用http包实现
reader.onLoadEnd.listen((event) {
var req = MultipartRequest('method', Uri.parse('uri'));
req.files.add(MultipartFile.fromString('key',
reader.result.toString().split(",").last));
req.fields['key']='value';
req.send();
});
以字符串的形式构造MultipartFile需要把reader的结果转成字符串,split(",").last是方便后端使用base64解码后保存文件。
3.使用dio包实现
reader.onLoadEnd.listen((event) {
var dio = Dio();
var multipart = MultipartFile.fromString(reader.result.toString().split(",").last,filename: file.name);
var formData = FormData.fromMap({'file':multipart,'data':'data'});
dio.post('url',data: formData);
});
如果想使用MultipartFile.fromBytes方法的构造上传文件的话,需要先获得字节 Uint8List
var bytes = Base64Decoder().convert(reader.result.toString().split(",").last);
var multipart = MultipartFile.fromBytes(bytes);
要注意的是,以字节的形式构造MultipartFile时,该文件上传的类型是octet-stream,在form中不能携带别的键值对,只能上传单文件,否则后端无法识别该请求。
如果文章出现问题,欢迎各位读者在评论区斧正。