Flutter Web 多部分formdata文件上传进度条

     2023-02-23     81

关键词:

【中文标题】Flutter Web 多部分formdata文件上传进度条【英文标题】:Flutter Web multipart formdata file upload progress bar 【发布时间】:2021-05-18 12:46:12 【问题描述】:

我正在使用 Flutter web 和strapi headless cms 作为后端。我能够成功发送文件,但想要它的进度指示。后端限制:文件上传必须是多部分表单数据,可以是缓冲区或流。前端限制:Flutter web 无权访问系统文件目录;文件必须加载到内存中并使用其字节发送。

我可以使用flutter的http包或Dio包上传文件,但是在尝试以某种方式访问​​上传进度时遇到以下问题:

Http 示例代码:

http.StreamedResponse response;

final uri = Uri.parse(url);
final request = MultipartRequest(
  'POST',
  uri,
);
request.headers['authorization'] = 'Bearer $_token';
request.files.add(http.MultipartFile.fromBytes(
  'files',
  _fileToUpload.bytes,
  filename: _fileToUpload.name,
));

response = await request.send();

var resStream = await response.stream.bytesToString();
var resData = json.decode(resStream);

我尝试了什么: 当访问 onData 的 response.stream 时,它只在服务器发送完成的请求时做出响应(即使方法声明它应该获得一些进度指示)。

Dio包代码

Response response = await dio.post(url,
    data: formData,
    options: Options(
      headers: 
        'authorization': 'Bearer $_token',
      ,
    ), onSendProgress: (int sent, int total) 
  setState(() 
    pm.progress = (sent / total) * 100;
  );

问题:

该包似乎能够获得一些进度指示,但 Flutter web 的 Dio 包有一个尚未修复的错误:请求阻塞 ui 并且应用程序冻结直到上传完成。

【问题讨论】:

dio 问题仍未解决:github.com/flutterchina/dio/issues/961github.com/flutterchina/dio/issues/925 【参考方案1】:

你好,可以使用universal_html/html.dart包做进度条,步骤如下:

    导入通用包
import 'package:universal_html/html.dart' as html;
    从 html 输入元素中选择文件,而不是使用文件选择器包
 _selectFile() 
    html.FileUploadInputElement uploadInput = html.FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.accept = '.png,.jpg,.glb';
    uploadInput.click();

    uploadInput.onChange.listen((e) 
      _file = uploadInput.files.first;
    );
 
    在 web 文件夹中创建 upload_worker.js,我的示例是上传到 S3 post presigned url
self.addEventListener('message', async (event) => 
    var file = event.data.file;
    var url = event.data.url;
    var postData = event.data.postData;
    uploadFile(file, url, postData);
);

function uploadFile(file, url, presignedPostData) 

    var xhr = new XMLHttpRequest();
    var formData = new FormData();

    Object.keys(presignedPostData).forEach((key) => 
        formData.append(key, presignedPostData[key]);
    );
    formData.append('Content-Type', file.type);
    // var uploadPercent;
    formData.append('file', file);

    xhr.upload.addEventListener("progress", function (e) 
        if (e.lengthComputable) 
            console.log(e.loaded + "/" + e.total);
            // pass progress bar status to flutter widget
            postMessage(e.loaded/e.total);
        
    );

    xhr.onreadystatechange = function () 
        if (xhr.readyState == XMLHttpRequest.DONE) 
            // postMessage("done");
        
    
    xhr.onerror = function () 
        console.log('Request failed');
        // only triggers if the request couldn't be made at all
        // postMessage("Request failed");
    ;

    xhr.open('POST', url, true);
    xhr.send(formData);

    Flutter web call upload worker 上传和监听进度条状态
class Upload extends StatefulWidget 
  @override
  _UploadState createState() => _UploadState();


class _UploadState extends State<Upload> 
  html.Worker myWorker;
  html.File file;

  _uploadFile() async 
    String _uri = "/upload";
    final postData = ;

    myWorker.postMessage("file": file, "uri": _uri, postData: postData);
  

  _selectFile() 
    html.InputElement uploadInput = html.FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.click();

    uploadInput.onChange.listen((e) 
      file = uploadInput.files.first;
    );
  

  @override
  void initState() 
    myWorker = new html.Worker('upload_worker.js');
    myWorker.onMessage.listen((e) 
      setState(() 
        //progressbar,...
      );
    );

    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Column(
      children: [
        RaisedButton(
          onPressed: _selectFile,
          child: Text("Select File"),
        ),
        RaisedButton(
          onPressed: _uploadFile,
          child: Text("Upload"),
        ),
      ],
    );
  

就是这样,希望对你有帮助。

【讨论】:

如何在 Flutter WEB 中上传文件到 API

...lutter新手,在将文件上传到API时遇到问题。我曾尝试使用FormData和MultiPartFile但它返回错误。我也在这个视频中使用了代码,但它不起作用:https://www.youtube.com/watch?v=c2tGUt7FLq 查看详情

将图像/文件上传到 Strapi (Flutter Web)

...utterWeb将图像上传到Strapi。我知道(来自link)我需要使用FormData来执行此操作。我研究了很多方法来做到这一点,我偶然发现了Dio,当然还有Http。两种解决方案都给了我错误:Unsupport 查看详情

下一个 js 应用程序中 formData 的“操作”多部分字段中的 JSON 无效?

】下一个js应用程序中formData的“操作”多部分字段中的JSON无效?【英文标题】:InvalidJSONinthe‘operations’multipartfieldinformDatainnextjsapplication?【发布时间】:2021-12-0403:53:03【问题描述】:我有一个这样的突变-mutationsignUp($avatar:Upload... 查看详情

未定义 FormData 时如何在 Web Workers 中上传文件

】未定义FormData时如何在WebWorkers中上传文件【英文标题】:HowtouploadfilesinWebWorkerswithoutusingFormData【发布时间】:2012-12-0123:49:18【问题描述】:当我通过WebWorker上传时,如何在PHP中检索$_FILES?当我尝试使用FormData时,出现以下错误... 查看详情

formdata实现上传多图片,学习使用formdata

FormData对象是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利。今天我们使用dropzone和FormData实现多文件上传功能。varSAMP=null;//Dropzone对象SAMP=newDropzone("#dropzone",{url:"#",//后台响应的链接maxFiles:4,//最大可... 查看详情

使用 Spring Rest 模板 + Spring Web MVC 进行多部分文件上传

】使用SpringRest模板+SpringWebMVC进行多部分文件上传【英文标题】:MultipartFileUploadUsingSpringRestTemplate+SpringWebMVC【发布时间】:2015-01-1321:25:17【问题描述】:我正在尝试使用带有以下代码的RestTemplate上传文件。MultiValueMap<String,Object... 查看详情

使用 AJAX + 多部分表单数据 + UTF-8 编码发送文件和文本

...文件和文本【英文标题】:SendingfilesandtextwithAJAX+multipartformdata+UTF-8encoding【发布时间】:2014-03-2808:56:43【问题描述】:我整天都在尝试让客户端在FormData()对象中使用UTF-8编码发送AJAX请求。我在服务器端使用SpingMVC,但这不适用于... 查看详情

微信小程序接口请求多文件+参数上传单文件+参数上传(formdata形式)微信小程序实现formdata格式传参(亲测有效)(代码片段)

01.引入所需formDatajs文件1.文件链接链接:https://pan.baidu.com/s/1BDxx0-1KMAnkceXb45L5rg提取码:6ibp2.引入使用constFormData=require('../../../../utils/formData.js')formData.js与mimeMap.js请确保在同一层级02.formData参数1.参数设置letdata= age:18, name:... 查看详情

如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用

】如何将带有附加数据的FormData文件发送到asp.netwebapiajax调用【英文标题】:HowtosendFormDatafileswithadditionaldatatoasp.netwebapiajaxcall【发布时间】:2019-09-0617:34:02【问题描述】:在这个项目中,我有一种输入和文件上传的形式,ajax调用... 查看详情

.NET Web API Blueimp 多文件上传错误“MIME 多部分流意外结束。MIME 多部分消息不完整。”

】.NETWebAPIBlueimp多文件上传错误“MIME多部分流意外结束。MIME多部分消息不完整。”【英文标题】:.NETWebAPIBlueimpmultiplefileuploaderror"UnexpectedendofMIMEmultipartstream.MIMEmultipartmessageisnotcomplete."【发布时间】:2021-05-1819:00:01【问题... 查看详情

Flutter Web - 如何选择 PDF 文件并 POST 到 API?

】FlutterWeb-如何选择PDF文件并POST到API?【英文标题】:FlutterWeb-HowtopickaPDFfileandPOSTtoanAPI?【发布时间】:2020-05-1504:42:12【问题描述】:我正在构建一个FlutterWeb应用程序,其中一部分用户可以从他们的计算机中选择一个或多个PDF。... 查看详情

是否可以在 Flutter Web 的同一页面中创建指向部分的链接?

】是否可以在FlutterWeb的同一页面中创建指向部分的链接?【英文标题】:Isitpossibletocreatelinkstosectionsinthesamepageinflutterweb?【发布时间】:2020-07-0115:52:54【问题描述】:我想使用FlutterWeb创建一个网站,但我无法导航到同一页面中的... 查看详情

如何将多部分文件转换为文件?

】如何将多部分文件转换为文件?【英文标题】:HowtoconvertamultipartfiletoFile?【发布时间】:2014-08-1123:05:57【问题描述】:谁能告诉我将多部分文件(org.springframework.web.multipart.MultipartFile)转换为文件(java.io.File)的最佳方法是什么?在... 查看详情

web前沿——html5formdata对象的使用

  XMLHttpRequestLevel2添加了一个新的接口——FormData。利用FormData 对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send() 方法来异步的提交表单。与普通的Ajax相比,使用FormData... 查看详情

将数组附加到 FormData 并通过 AJAX 发送

】将数组附加到FormData并通过AJAX发送【英文标题】:appendingarraytoFormDataandsendviaAJAX【发布时间】:2013-04-1219:33:26【问题描述】:我正在使用ajax提交包含数组、文本字段和文件的多部分表单。我将每个VAR附加到主数据中varattachments=... 查看详情

flutter web pwa如何支持多域链接打开主屏应用?

】flutterwebpwa如何支持多域链接打开主屏应用?【英文标题】:Howtosupportmultipledomainlinkstoopenhomescreenappforflutterwebpwa?【发布时间】:2021-03-0221:49:34【问题描述】:问题是,当用户从谷歌安装主屏幕应用程序时,会形成一个链接,例... 查看详情

如果在 iOS 和 Android 上的 Web 应用程序中使用 FormData 发送文件,则转换为 [Object object] 字符串

】如果在iOS和Android上的Web应用程序中使用FormData发送文件,则转换为[Objectobject]字符串【英文标题】:Fileconvertedto[Objectobject]stringifsentusingFormDatainwebapponiOS&Android【发布时间】:2013-05-2409:47:12【问题描述】:我正在构建一个基于... 查看详情

Flutter web javascript文件集成

】Flutterwebjavascript文件集成【英文标题】:Flutterwebjavascriptfileintegration【发布时间】:2021-09-0511:09:51【问题描述】:我正在处理这个项目,其中已经有一些文件可以从套接字压缩数据。但不幸的是,这些文件是用javascript编写的。... 查看详情