如何使用 axios 将文件上传到亚马逊 s3 存储桶?

Posted

技术标签:

【中文标题】如何使用 axios 将文件上传到亚马逊 s3 存储桶?【英文标题】:How to upload file to amazon s3 bucket using axios? 【发布时间】:2018-01-23 00:29:08 【问题描述】:

首先,我对反应非常陌生。我正在尝试使用 axios 将文件上传到我的亚马逊 S3 存储桶。 我得到了正确的签名网址,但我不知道如何继续。我试过了,但它不起作用。

我得到的错误如下: 跨域请求被阻止:同源策略不允许读取位于https://xxx.s3.amazonaws.com/wolves.jpeg?AWSAccessKeyId=xxxxxxxxxx&Content-Type=image%2Fjpeg&Expires=1502773987&Signature=ZXQya8d3xZoikzX6dIbdL3Bvb8A%3D 的远程资源。 (原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。

import React,  Component  from 'react'
import Dropzone from 'react-dropzone'
import aws from 'aws-sdk'
import axios from 'axios'

export default class ImageAWS extends Component

    uploadFile(files)

        console.log('uploadFile: ')
        const file = files[0]

        aws.config.update(
            accessKeyId: 'xxxxxxxxx',
            secretAccessKey: 'xxxxxxxx'
        );

        var s3 = new aws.S3();

        var params = 
        Bucket: 'xxx',
        Key: file.name,
        Expires: 60,
        ContentType: file.type
    ;

    s3.getSignedUrl('putObject', params, function(err, signedUrl) 
        if (err) 
            console.log(err);
            return err;
         else 
            console.log(signedUrl);

            var instance = axios.create();

            instance.put(signedUrl, file, headers: 'Content-Type': file.type)
                .then(function (result) 
                    console.log(result);
                )
                .catch(function (err) 
                    console.log(err);
                );
            return signedUrl;
        
    );



render () 
    return (
        <div>
            Images Component
            <Dropzone onDrop=this.uploadFile.bind(this) />
        </div>

    )

OPTIONS https://xxbucket.s3.amazonaws.com/wolves.jpeg?
AWSAccessKeyId=xxxxxxxxxxxxxxxxxx&Content-Type=image%2Fjpeg&Expires=1502894764&Signature=FqAccUimhyrLgLBldVy%2Fkyx2Xmc%3D HTTP/1.1

Host: xxbucket.s3.amazonaws.com

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 
Firefox/54.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate, br

Access-Control-Request-Method: PUT

Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-methods,access-control-allow-origin

Origin: http://localhost:8080

Connection: keep-alive





HTTP/1.1 403 Forbidden

x-amz-request-id: 4282B87BA935EF9A

x-amz-id-2: jWOwOQ/7BCzvw1xPmJroOzUBhbCmpfGx5HCPaPUvMoYTFMrlhoG5wN902B1brZ5cjYnKHMLWmpQ=

Content-Type: application/xml

Date: Wed, 16 Aug 2017 14:45:05 GMT

Server: AmazonS3

Content-Length: 514



  <?xml version="1.0" encoding="UTF-8"?>
 <Error><Code>AccessForbidden</Code><Message>CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Request-Headers are not whitelisted by the resource's CORS spec.</Message><Method>PUT</Method><ResourceType>OBJECT</ResourceType><RequestId>4282B87BA935EF9A</RequestId><HostId>jWOwOQ/7BCzvw1xPmJroOzUBhbCmpfGx5HCPaPUvMoYTFMrlhoG5wN902B1brZ5cjYnKHMLWmpQ=</HostId></Error>

【问题讨论】:

【参考方案1】:

您需要将所需的 CORS 标头添加到您的开发服务器。 Read about CORS。根据您的开发服务器,搜索添加响应标头的正确方法。然后,将以下标头添加到每个响应中:

"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"

这将允许从网络上的其他网站请求数据。确保仅将它们添加到开发版本(我假设您正在学习,所以没关系)。在生产环境中,您需要将“Access-Control-Allow-Origin”:“*”限制为特定的 url。

进一步阅读:

webpack dev server CORS issue https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

【讨论】:

感谢您的回答。我已将标头添加到 webpack,但它仍然无法正常工作。我收到相同的错误消息。 你能提供完整的http会话记录(带有标题和正文)吗?您可以为此使用 fiddler2。 我成功了,这与我的代码无关。这是关于 s3 存储桶中的 CORS 属性。我已经 Authorization 和 * 修复了它。再次感谢您。【参考方案2】:

对于从前端上传文件时遇到此问题的人, 转到 AWS S3 -> 选择您的存储桶 -> 权限选项卡 -> 滚动到最后一个

在跨域资源共享 (CORS) 部分下,编辑并删除您的配置

[
    
        "AllowedHeaders": [
            "Authorization",
            "Content-Range",
            "Accept",
            "Content-Type",
            "Origin",
            "Range",
            "Access-Control-Allow-Origin"
        ],
        "AllowedMethods": [
            "GET",
            "PUT"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "Content-Range",
            "Content-Length",
            "ETag"
        ],
        "MaxAgeSeconds": 3000
    
]

您可以根据自己的要求进行编辑。

最后,发布/保存它。

这将解决您的 CORS 问题。

【讨论】:

以上是关于如何使用 axios 将文件上传到亚马逊 s3 存储桶?的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有子文件夹的文件夹上传到亚马逊 s3?

vue express将多个文件上传到亚马逊s3

如何在不使用 SDK 的情况下将文件从 Android 上传到 Amazon S3

如何使用 django-storages 将图像上传到亚马逊 S3?在管理员中上传有效,但在网站表单中无效

如何使用 django (python) 和 s3 上传文件?

如何将画布数据 uri 上传到亚马逊 s3 服务器