从前端上传视频到预签名 URL

Uploading a video to the presigned URL from Frontend

我已经使用我的后端代码生成了预签名 URL,然后使用该 URL 上传了在 session 期间录制的视频。我在前端(React JS)中使用以下代码上传视频,预检似乎因 403 Forbidden 而失败,并且 post 请求因 cors 错误而失败。详情请见下方:

使用的代码:

static async uploadVideoToS3(url, body) {
        try {
            const myHeaders = new Headers({ 'Content-Type': 'video/mp4', 'mode': 'no-cors' });
            const response = fetch(url, {
                method: 'POST',
                headers: myHeaders,
                body: body
            });
            return response;
        } catch (error) {
            toast(error);
            console.log(error);
        }
    } 

控制台错误: CORS 策略阻止了从源 'http://localhost:5000' 在 'https://xxxxxxxxxx' 获取的访问权限:对预检请求的响应未通过访问控制检查:没有 'Access-Control-Allow-Origin' header 出现在请求的资源。如果不透明的响应满足您的需求,请将请求的模式设置为 'no-cors' 以在禁用 CORS 的情况下获取资源。

注意:将预签名 URL 更改为 xxxxxxxxxx 以避免泄漏 post 中的详细信息。

问题可能是我 运行 所有这些都在本地主机上吗?或者是 AWS S3 存储桶上的 CORS 配置导致了这个问题?或者我的请求中是否缺少 header?

我发现一个 post 有类似的问题: OP 回复说问题已解决,但他们从未提及解决方案。

尝试将 proxy 添加到 package.json 文件并添加您要向其发送请求的服务器的 url,在您的情况下 localhost:5000

"proxy": "http://localhost:5000"

然后使用 npm start 重新启动您的应用并更改 component 中的 url,如果您这样做的话

const res = fetch('https://localhost:5000/api/user')

然后改变它并像下面那样做

const res = fetch('/api/user')

如果上述解决方案不起作用,则可能是您的后端有问题。

我也是这么想的,当我试图从本地访问 URL 时,这个问题不是在安全主机 (HTTP) 上提供的。所以我在开发环境中部署了该应用程序,但遇到了同样的问题。经过一些研究,我能够解决这个问题。看来我需要修改我试图从中生成 pre-signed URL 的 S3 存储桶的 CORS 配置。

在生成 pre-signed URL 之前,我添加了下面的一段代码,它更改了 S3 存储桶的 CORS 配置,因为我也是从我的本地访问它的,所以我把现在允许 Origins 为 * 但在投入生产之前,我会将其更改为 prod URL.

//passing AWS credentials            
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
            
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                    .withRegion(clientRegion)
                    .build();
//Creating CORS List to update the CORS Configuration
                List<String> allowedHeaders=new ArrayList<String>();  
                allowedHeaders.add("*");
                
                List<AllowedMethods> allowedMethods=new ArrayList<AllowedMethods>();  
                allowedMethods.add(0, AllowedMethods.GET);
                allowedMethods.add(1, AllowedMethods.PUT);
                
                List<String> allowedOrigins=new ArrayList<String>();  
                allowedOrigins.add("*");
                
                List<String> exposedHeaders=new ArrayList<String>();  
                exposedHeaders.add("GET");
                exposedHeaders.add("PUT");
                
                CORSRule cors = new CORSRule();
                cors.setAllowedHeaders(allowedHeaders);
                cors.setAllowedMethods(allowedMethods);
                cors.setAllowedOrigins(allowedOrigins);
                cors.setExposedHeaders(exposedHeaders);
                cors.setMaxAgeSeconds(3600);
                
                //Assigning CORS List to CORS Configuration
                BucketCrossOriginConfiguration CORSConfiguration = new BucketCrossOriginConfiguration();
                CORSConfiguration.withRules(cors);
                
                //Updating CORS Configuration
                s3Client.setBucketCrossOriginConfiguration(bucketName, CORSConfiguration);

或者,您也可以从 frontend/other 语言修改 CORS,参考: Javascript: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketCors-property 其他语言: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html#API_PutBucketCors_SeeAlso