如何使用节点,createPresignedPost和提取将图像文件直接从客户端上传到AWS S3

问题描述 投票:2回答:1

我正在使用s3.createPresignedPost()在我的服务器上生成一个AWS S3预签名发布对象。然后,我尝试使用预签名的发布网址和字段通过访存直接从客户端将文件直接上传到S3存储桶,但得到了s3.createPresignedPost()

我尝试将表单字段手动添加到我的FormData对象以直接匹配此示例:403 Forbidden,但继续收到403错误。

用于生成发布对象的服务器端功能

    const AWS = require(“ aws-sdk / global”);    const S3 = require(“ aws-sdk / clients / s3”);    const uuidv4 = require(“ uuid / v4”);    AWS.config.update({      accessKeyId:process.env.S3_KEY_ID,      secretAccessKey:process.env.S3_SECRET_KEY,      地区:“ us-east-1”    });    const s3 = new S3();    const getPresignedPostData =(存储桶,目录)=> {      const key =`$ {directory} / $ {uuidv4()}`;      const postData = s3.createPresignedPost({        斗:斗,        字段:{键:键,success_action_status:“ 201”},        条件:[{acl:“公开阅读”}],        ContentType:“图像/ *”,        过期:300      });      返回postData;    };

返回类似如下的内容:

    {      字段:{        关键字:“ 5cd880a7f8b0480b11b9940c / 86d5552b-b713-4023-9363-a9b36130a03f”        策略:{Base64编码的策略字符串}        X-Amz-算法:“ AWS-HMAC-SHA256”        X-Amz凭证:“ AKIAI4ELUSI2XMHFKZOQ / 20190524 / us-east-1 / s3 / aws4_request”        X-Amz-日期:“ 20190524T200217Z”        X-Amz签名:“ 2931634e9afd76d0a50908538798b9c103e6adf067ba4e60b5b54f90cda49ce3”        桶:“图片完美照片”        success_action_status:“ 201”      },      网址:“ https://s3.amazonaws.com/picture-perfect-photos”    }

我的客户端功能看起来像:

    const uploadToS3 =异步({字段,网址},文件)=> {        const formData = new FormData();        Object.keys(fields).forEach(key => formData.append(key,fields [key]));        formData.append(“ file”,file);        尝试{          const config = {            方法:“ POST”,            正文:formData          };          const response =等待fetch(url,config);          如果(!response.ok){            抛出新的错误(response.statusText);          }          const data =等待response.json();          返回数据;        } catch(err){          console.log(err.message);        }      };

我的S3存储桶CORS配置如下:

                     *  AllowedOrigin>        获取 AllowedMethod>        开机自检 AllowedMethod>         PUT  AllowedMethod>        删除 AllowedMethod>         *  AllowedHeader>     CORSRule>     CORSConfiguration>

我希望获得设置为https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html时发送的XML文档,但仍在不断获取success_action_status: "201"

node.js amazon-s3 fetch
1个回答
0
投票

我刚遇到同样的问题。

在S3控制台中为S3存储桶的CORS规则添加403 Forbidden<AllowedMethod>PUT</AllowedMethod>

<AllowedHeader>Content-*</AllowedHeader>

向服务器发出发布请求以获取预先签名的S3 URL。发布请求的正文中应包含文件名和mime类型:

快速路线:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>Content-*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

选择要上传的文件时,异步功能中的客户端代码:

app.post("/s3-signed-url",async (req, res, next)=>{
    const s3 = new AWS.S3();
    const url = await s3.getSignedUrlPromise('putObject', {
        Bucket: "BUCKET_NAME",
        Key: req.body.name,
        ContentType: req.body.type,
        Expires: 60,
        ACL: 'public-read',
    });
    res.json({signedUrl: url})
});

[我的致命错误是,在上传带有签名URL的文件时,我在async function onFileDrop(file){ const {name, type} = file; // I use react-dropzone to obtain the file. const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({name,type}) } const rawResponse = await fetch("/s3-signed-url", options) const {signedUrl} = await rawResponse.json(); // After you obtain the signedUrl, you upload the file directly as the body. const uploadOptions = { method: 'Put', body: file,} const res = await fetch(signedUrl, uploadOptions); if(res.ok) { return res.json() } } 中添加了多余的标头。我遇到其他声称我必须显式添加“ Content-Type”标头的线程:

uploadOptions

但是对于我来说,这完全没有必要,这就是我收到403错误的原因。

© www.soinside.com 2019 - 2024. All rights reserved.