【问题标题】:Can`t upload files to a private aws S3 bucket无法将文件上传到私有 aws S3 存储桶
【发布时间】:2021-10-11 07:50:59
【问题描述】:

我正在尝试使用 nodeJS 服务器和 React 客户端应用程序将文件上传到 aws S3。我是aws的新手,所以我想我做错了什么。我创建了一个完全私有的备份,以便只有应用程序可以访问文件。问题是当我想上传文件时,我需要获取链接 myBucket.getSignedUrl () 才能上传。当我这样做并将其发送到前端时,前端使用我要上传的文件获取到 S3 的链接,问题是它返回以下错误:

访问获取 'https://atlasworld-progress.s3.amazonaws.com/IMG_20210202_100322.jpg?AWSAccessKeyId=AKIAZGHWWSFL5XOWPRXJ&Content-Type=image%2Fjpeg&Expires=1633937718&Signature=o8S8MQQ3fVdONePGOT4a5ic7CcU%3D' 来自原点“http://localhost:3000”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

这里是aws配置文件:

import AWS from 'aws-sdk'

AWS.config.update({
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_KEY
})

const S3_BUCKET ='atlasworld-progress';
const REGION =process.env.AWS_REGION;
const URL_EXPIRATION_TIME = 60; // in seconds

const myBucket = new AWS.S3({
    params: { Bucket: S3_BUCKET},
    region: REGION,
})

export const generatePreSignedPutUrl = async (fileName, fileType) => {
    const url = await myBucket.getSignedUrl('putObject', {
        Key: fileName,
        ContentType: fileType,
        Expires: URL_EXPIRATION_TIME
    });
   return url;
}

在 express 控制器中,它只是将由函数 generatePreSignedPutUrl() 生成的链接返回给客户端。 下面是 React 中前端函数的代码:

const [frontPhoto, setFrontPhoto] = useState();
const upload = async (e) => {
    e.preventDefault();
    await JWT.checkJWT();

    const requestObject = {
        fileName: frontPhoto.name,
        fileType: frontPhoto.type,
        token: JWT.getToken()
    };

    axiosReq.post(`${serverPath}/prepare_s3`, requestObject).then((res) => {
    //the following fetch is the one that fails
      fetch(res.data, {
        method: "PUT",
        body: frontPhoto,
      }).then((res) => {
        console.log(res);
      });
    });
}

如果有人知道发生了什么,我将不胜感激。

我还想问一下 S3 一次只能上传一个文件,还是一次 fetch 可以上传不同的文件。

谢谢!

【问题讨论】:

    标签: node.js amazon-web-services amazon-s3


    【解决方案1】:

    我认为这说明了一切:

    CORS 策略已阻止从源“http://localhost:3000”获取的访问权限

    您需要熟悉CORS。如果你想让它工作,那么你需要enable CORS from AWS

    【讨论】:

    • 谢谢,我配置了 CORS,但现在我得到 400(错误请求),知道可能是什么错误吗?
    • @Gonsa02 新错误将成为新问题的候选者。根据这些信息,我不得不说不,没有想法
    【解决方案2】:

    这是一个nginx配置问题,你必须在nginx.conf中增加你的client_max_body_size

    步骤:

    1. 通过 ssh 连接到您的 Beanstalk/EC2 实例:

      ssh -i <key.pem> <ec2-user>@<host>

    2. 以超级用户身份登录:

      $ sudo su

    3. 编辑 nginx.conf

      nano /etc/nginx/nginx.conf

    4. 在 http 块内添加这一行

      client_max_body_size 50M;

    5. 保存文件

    6. 重启nginx服务

      $ service nginx restart

    示例 NGINX 配置文件

    # Elastic Beanstalk Nginx Configuration File
    
    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log;
    
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
    
        client_max_body_size 50M;           --------- add this line
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        access_log    /var/log/nginx/access.log;
    
        log_format  healthd '$msec"$uri"$status"$request_time"$upstream_response_time"$http_x_forwarded_for';
    
        include       /etc/nginx/conf.d/*.conf;
        include       /etc/nginx/sites-enabled/*;
    }
    

    【讨论】:

    • 我没有使用 EC2,它只是一个 React 和 NodeJS 应用,但我需要使用 S3 来存储照片。
    • 您的 nodejs 应用程序正在本地主机上运行? @Gonsa02
    猜你喜欢
    • 2017-10-17
    • 2018-08-13
    • 2018-04-25
    • 2012-09-08
    • 2018-03-25
    • 2017-09-24
    • 2018-04-04
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多