Node.js 无法通过nodejs在aws s3上上传图像,并使用预先签名的url进行颤振

Node.js 无法通过nodejs在aws s3上上传图像,并使用预先签名的url进行颤振,node.js,amazon-s3,flutter,Node.js,Amazon S3,Flutter,我试图通过nodejs使用aws s3 bucket和预先签名的url,通过dart/FLAtter进行图像上传。我成功地生成了预签名的url并将其发送回前端,但无法通过s3和文件发出put请求。如果我正在打印状态码,我将获得400 import 'dart:io'; import 'dart:convert'; import 'package:path/path.dart'; import 'package:async/async.dart'; import 'package:flutter

我试图通过nodejs使用aws s3 bucket和预先签名的url,通过dart/FLAtter进行图像上传。我成功地生成了预签名的url并将其发送回前端,但无法通过s3和文件发出put请求。如果我正在打印状态码,我将获得400

 import 'dart:io';
import 'dart:convert';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';
import '../global.dart';

class AddAccount extends StatelessWidget {
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        iconTheme: IconThemeData(
          color: Colors.grey
        ),
        title: Text('Add Account', style: TextStyle(color: Colors.black54, fontSize: 20.0)),
        backgroundColor: Colors.white,
      ),
      body: addAccountBody(context),
    );
  }
  Widget addAccountBody(context){
    return ListView(
      children: <Widget>[
        TextField(
          decoration: InputDecoration(
            labelText: 'email'
          ),
          textCapitalization: TextCapitalization.characters,
        ),

        TextField(
          decoration: InputDecoration(
            labelText: 'name'
          ),
          textCapitalization: TextCapitalization.characters,
        ),
        OutlineButton(
          onPressed: (){
            openImagePicker(context);
          },
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(Icons.camera_alt),
              Text('add image')
            ],
          ),
        )
      ],
    );
  }
  void openImagePicker(BuildContext context){
    showModalBottomSheet(
      context: context,
      builder: (BuildContext context) {
        return Container(
          height: 80.0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              IconButton(
                onPressed: (){
                  getImage(context, ImageSource.camera);
                },
                icon: Icon(Icons.camera_alt),
              ),
              SizedBox(width: 20.0,),
              IconButton(
                onPressed: () async {
                  File image = await getImage(context, ImageSource.gallery);
                  http.Response response = await http.get('$url1/api/upload', headers: {
                    "x-auth" : 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzQ0M2M0NDE0NjkxODM3ZTQxNTMxZTgiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ3OTc1NzQ5fQ.73_tyhu3vTpsnMncmjTS0xDBec08pScxpa35yRlLuzQ'
                  });
                  Map<String, dynamic> uploadUrl = json.decode(response.body);
                  final dataType = lookupMimeType(image.path).split("/");
                  final imageUploadRequest = http.MultipartRequest("PUT", Uri.parse(uploadUrl['url']));
                  final file = await http.MultipartFile.fromPath("${uploadUrl['key']}", image.path, contentType: MediaType(dataType[0], dataType[1]));
                  imageUploadRequest.files.add(file);
                  imageUploadRequest.fields['user'] = Uri.encodeComponent('user');
                  imageUploadRequest.headers['Content-Type'] = 'image/jpeg';
                  print(file.contentType);
                  try{
                    final streamedResponse = await imageUploadRequest.send();
                    final res = await http.Response.fromStream(streamedResponse);
                     print(res.statusCode);
                  }catch(e){
                    print(e);
                  }
                },
                icon: Icon(Icons.camera),
              ),

            ],
          ),
        );
      }
    ); 
  }
  Future<File> getImage(BuildContext context, ImageSource sourse) async {
    File file = await ImagePicker.pickImage(source: sourse, maxWidth: 400.0);
    Navigator.pop(context);
    return file;

  }
}

节点代码

S3预签名的URL需要原始字节作为正文,而不是多部分文件。因此,我使用了以下代码:

List<int> content = await file.readAsBytes();

var streamed = http.StreamedRequest("PUT", Uri.parse(url));
streamed.headers["Content-Type"] = mimeType;
streamed.headers["Content-Length"] = "${content.length}";
streamed.sink.add(content);
streamed.sink.close();

var response = await streamed.send();
List content=wait file.readAsBytes();
var streamed=http.StreamedRequest(“PUT”,Uri.parse(url));
流式.headers[“内容类型”]=mimeType;
streamed.headers[“Content-Length”]=“${Content.Length}”;
流式.接收器.添加(内容);
streamed.sink.close();
var response=wait streamed.send();
List<int> content = await file.readAsBytes();

var streamed = http.StreamedRequest("PUT", Uri.parse(url));
streamed.headers["Content-Type"] = mimeType;
streamed.headers["Content-Length"] = "${content.length}";
streamed.sink.add(content);
streamed.sink.close();

var response = await streamed.send();