尽管图像预览看起来不错,但带有流星的React Dropzone上传器却提供了error_upload

时间:2019-12-17 16:46:04

标签: reactjs amazon-s3 meteor dropzone

我正在尝试在Meteor / React应用程序中将图像文件上传到AWS S3存储桶。

我正在使用React Dropzone Uploader

版本:

METEOR@1.8.1
"react": "^16.11.0"
"react-dropzone-uploader": "^2.11.0"

除了S3存储桶本身之外,所有其他东西都在我的本地开发计算机上运行。

当我将图像拖到浏览器中的dropzone上传器上时,我看到进度条,然后是图像预览,但是控制台显示消息“ error_upload”,并且“提交”按钮被禁用。

如果上传响应的HTTP状态代码> = 400,则根据docs设置error_upload,但是我不明白这是什么意思。图像预览看起来不错,URL已经正确生成,并且我还没有尝试执行实际上传到AWS的操作。

据我所知,一切都以正确的顺序进行:客户端控制台以以下形式记录我的signedUrl:

signedUrl in client https://my-bucket.s3.amazonaws.com/test/DA8acSgM3wQtrReEK/userpic.jpg?AWSAccessKeyId=somekeyid&Expires=1576600622&Signature=somestuff

然后登录“上传”并显示看起来像有效的对象详细信息:

height: 100
​id: "1576600322132-0"
​lastModifiedDate: "2014-01-21T17:00:42.000Z"
​name: "userpic.jpg"
​percent: 0
​previewUrl: "blob:http://127.0.0.1:3000/80aaa9bd-b7b8-492e-8e13-8c8b971e4998"
​size: 5203
​status: "uploading"
​type: "image/jpeg"
​uploadedDate: "2019-12-17T16:32:02.137Z"
​width: 100

然后,客户端控制台最终显示:

error_upload
height: 100
​id: "1576600322132-0"
​lastModifiedDate: "2014-01-21T17:00:42.000Z"
​name: "userpic.jpg"
​percent: 100
​previewUrl: "blob:http://127.0.0.1:3000/80aaa9bd-b7b8-492e-8e13-8c8b971e4998"
​size: 5203
​status: "error_upload"
​type: "image/jpeg"
​uploadedDate: "2019-12-17T16:32:02.137Z"
​width: 100

这是我的代码:

客户端:

import React from 'react';
import 'react-dropzone-uploader/dist/styles.css';
import Dropzone from 'react-dropzone-uploader';

const callWithPromise = (method, myParameters) => {
    return new Promise((resolve, reject) => {
        Meteor.call(method, myParameters, (err, res) => {
            if (err) reject('Something went wrong');

            resolve(res);
        });
    });
};

const DropzoneUploader = ({ docId }) => {
    const getUploadParams = async ({ meta }) => {
        const signedUrl = await callWithPromise('getUploadParams', { 'key': `test/${docId}/${meta.name}` });
        console.log('signedUrl in client', signedUrl);
        return { 'url': signedUrl };
    };

    // called every time a file's `status` changes
    const handleChangeStatus = ({ meta, file }, status) => { console.log(status, meta, file); };

    // receives array of files that are done uploading when submit button is clicked
    const handleSubmit = (files, allFiles) => {
        console.log(files.map((f) => f.meta));
        allFiles.forEach((f) => f.remove());
    };

    return (
        <Dropzone
            getUploadParams={getUploadParams}
            onChangeStatus={handleChangeStatus}
            onSubmit={handleSubmit}
            accept="image/*,audio/*,video/*"
        />
    );
};

export default DropzoneUploader;

服务器:aws.js

const AWS = require('aws-sdk');

const s3 = new AWS.S3();

const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;

AWS.config.update({ 'accessKeyId': accessKeyId, 'secretAccessKey': secretAccessKey });

const myBucket = process.env.AWS_BUCKET;
const signedUrlExpireSeconds = 60 * 5;

const getSignedUrl = (key) => s3.getSignedUrl('putObject', {
    'Bucket': myBucket,
    'Key': key,
    'Expires': signedUrlExpireSeconds,
});

export default getSignedUrl;

服务器:Methods.js

Meteor.methods({
'getUploadParams': function ({ key }) {
        const signedUrl = getSignedUrl(key);
        console.log('signedUrl on server', signedUrl);
        return signedUrl;
    },
});

存储桶上的CORS配置:

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

对于我做错了什么,我将不胜感激。谢谢!

更新:“网络”标签显示对我的signedUrl的调用禁止使用状态码403“ SignatureDoesNotMatch”,这让我感到惊讶,因为在用户单击浏览器中的“提交”之前,我不认为它将尝试上传文件。所以也许问题出在我的AWS凭证上?但是我想确切地知道此阶段的url请求是什么情况。

更新2:我已将s3.getSignedUrl函数更改为指定“ putObject”而不是“ getObject”,但仍无法正常工作。从“网络”标签中可以看到,请求实际上是作为POST发送的,但是我不知道如何更改它?

0 个答案:

没有答案