【问题标题】:Upload Image/File to Strapi (Flutter Web)将图像/文件上传到 Strapi (Flutter Web)
【发布时间】:2020-11-28 12:22:09
【问题描述】:

我正在尝试通过 Flutter Web 将图像上传到 Strapi。我知道(来自link)我需要使用 FormData 来执行此操作。我研究了很多方法来做到这一点,我偶然发现了Dio,当然还有Http

两种解决方案都给了我错误: Unsupported operation: MultipartFile is only supported where dart:io is available.

我试过这段代码:

var request = new http.MultipartRequest("POST", Uri.parse(url));
    request.files.add(
      await http.MultipartFile.fromPath(
        "files",
        imageFilePath,
      ),
    );
    request.send().then((response) {
      if (response.statusCode == 200) print("Uploaded!");
      print(response.statusCode);
    }).catchError((e) => print(e));

按照here的建议。

当我使用MultipartFile.fromBytes(...) 时,还有许多其他错误或空数据 (400)。

我只是想上传一个文件,因此我假设我的正文应该只包含 files 的 FormData,正如 Strapi's Documentation 中提到的那样。

【问题讨论】:

    标签: flutter form-data strapi dio flutter-http


    【解决方案1】:

    所以,我在 Flutter Discord 上搜索了一些帮助,发现我的问题是因为 Flutter Web 不能使用 'dart:io' ,而使用 'dart:html' 会占用 Flutter 的所有平台。

    我最终使用了这个导入:

    import 'dart:convert';
    import 'dart:typed_data';
    import 'package:image_picker/image_picker.dart';
    import 'package:http/http.dart' as http;
    import 'package:http_parser/http_parser.dart';
    import 'package:path/path.dart';
    import 'package:async/async.dart';
    

    这是我创建和工作的函数:

     Future<bool> uploadImage(
        String imageFilePath,
        Uint8List imageBytes,
      ) async {
        String url = SERVERURL + "/uploadRoute";
        PickedFile imageFile = PickedFile(imageFilePath);
        var stream =
            new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
    
        var uri = Uri.parse(url);
        int length = imageBytes.length;
        var request = new http.MultipartRequest("POST", uri);
        var multipartFile = new http.MultipartFile('files', stream, length,
            filename: basename(imageFile.path),
            contentType: MediaType('image', 'png'));
    
        request.files.add(multipartFile);
        var response = await request.send();
        print(response.statusCode);
        response.stream.transform(utf8.decoder).listen((value) {
          print(value); 
        });
    

    我在使用 Strapi 时遇到了这个问题,这个解决方案非常有效。

    【讨论】:

    • 什么是 DelegatingStream ?
    【解决方案2】:

    使用 Flutter 创建条目时上传文件

    dio: ^3.0.10mime: ^1.0.0http_parser

    如果是foo,主要是文件的key name,所以上传文件需要把files.image改成files.foo

    final mimeType = mime.lookupMimeType(imageFile.path, headerBytes: [0xFF, 0xD8])?.split('/');
    
    FormData formData = new FormData.fromMap(
      {
        "files.image": await MultipartFile.fromFile(
          imageFile.path,
          filename: imageFile.path.split('/').last,
          contentType: MediaType(mimeType?[0], mimeType?[1]),
        ),
        "data": jsonEncode({
          "title": title,
          "summary": summary,
          "content": content,
        }),
      },
    );
    
    Response response = await _dio.post(
      "/blogs",
      data: formData,
      options: Options(),
    );
    

    【讨论】:

    • 错误:不支持的操作:仅当 dart:io 可用时才支持 MultipartFile。
    • 错误:不支持的操作:仅当 dart:io 可用时才支持 MultipartFile。
    【解决方案3】:

    在 Flutter Web 中:
    我正在使用带有 express 作为后端源的 node.js 我创建了以下简单的方法来使用 xamp图像和文本数据 上传到 localhost 服务器

    String url = 'http://localhost:8080/blog_upload';
        var request = http.MultipartRequest('POST', Uri.parse(url));
        imagebytes = await image.readAsBytes();
        List<int> listData = imagebytes!.cast();
        request.files.add(http.MultipartFile.fromBytes('field_name', listData ,
            filename:'myFile.jpg'));
     request.fields['name'] = 'Mehran Ullah Khan';
     request.fields['country'] = 'Pakistan';
        var response = await request.send();
    

    我在上面的方法中使用了以下依赖。

     http: ^0.13.3
     image_picker: ^0.8.2
    

    我们如何使用 image_picker? 首先全局声明imageimagebytes

    image = await ImagePicker().pickImage(source: ImageSource.gallery);
    

    这是我在后端使用的方法。

    app.post('/blog_upload', upload.single('field_name'), async (req, res, next) => {
      let data = {name_db: req.body['name'],    Country_db:req.body['country'],};
        let sqlq = `INSERT INTO TableName SET ? `;
        db.query(sqlq, data, (insertionErr, insertionResult) => {
          if (insertionErr) {
            console.log('failed_upload');
            throw insertionErr;
          }
          else {
            console.log('done_upload');
            res.send(insertionResult);  
          }
        });
      });
    

    在上面我使用过的方法中 multer and express 包 您可以在此link 中查看 multer 和 express 的完整详细信息

    【讨论】:

      【解决方案4】:

      @Diego Cattarinich Clavel

      字符串 url = 常量.BASE_URL + HttpUrls.categories; PickedFile imageFile = PickedFile(path); 变量流 = 新的 http.ByteStream(DelegatingStream.typed(imageFile.openRead()));

      var uri = Uri.parse(url);
      int length = imageBytes.length;
      var request = new http.MultipartRequest(
        "PUT",
        uri,
      );
      
      var multipartFile = new http.MultipartFile(
        'files.categoryImage',
        stream,
        length,
        filename: basename(imageFile.path),
        contentType: MediaType('image', 'png'),
      );
      
      request.files.add(multipartFile);
      request.fields['data'] = '{"category":$category}';
      print(request.url);
      
      var response = await request.send();
      print(response.statusCode);
      response.stream.transform(utf8.decoder).listen((value) {
        print(value);
      });
      

      【讨论】:

        猜你喜欢
        • 2020-04-30
        • 1970-01-01
        • 1970-01-01
        • 2021-08-11
        • 1970-01-01
        • 2021-07-03
        • 2020-08-13
        • 2021-12-25
        • 2021-07-28
        相关资源
        最近更新 更多