Axios AWS S3 Put对象:错误:网络错误

时间:2018-06-10 12:24:44

标签: reactjs amazon-web-services express amazon-s3 axios

我可以成功从AWS获取已签名的网址但我仍然在尝试放入文件时出错。

// Server.js

server.get('/...', (req, res) => {
const s3 = new AWS.S3();
const fileName = req.query.filename;
const fileType = req.query.filetype;

const s3Params = {
  Bucket: '...',
  Key: fileName,
  Expires: 60,
  ContentType: fileType,
  ACL: 'public-read'
};

s3.getSignedUrl('putObject', s3Params, (err, signedUrl) => {
  if (err) {
    console.log('s3 signed url err', err);
    return res.end();
  }

  const returnData = {
    signedUrl,
    url: `https://....s3.amazonaws.com/${fileName}`
  };

  res.send(JSON.stringify(returnData));
});

});

//反应

class ImageUploader extends React.Component {

onDrop = files => {
    // const file = files[0];
    // const fileName = file.name;

    var file = files[0];

    axios.get('/...', {
      params: {
        filename: 'home/banner-images/' + file.name,
        filetype: file.type
      }
    })
    .then(result => {

      const options = {
        headers: {
          'Content-Type': file.type,
          'Access-Control-Allow-Origin': '*',
          "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
          "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
        }
      };

      const instance = axios.create();
      return instance.put(result.data.signedUrl, file, options);
    })
    .then(result => {
      console.log('then then result', result);
    })
    .catch(err => {
      console.log('s3 put err', err);
    });
  };

  render() {
    return (
      <div>
        <Dropzone onDrop={this.onDrop}>
          <div>
            Try dropping a file here, or click to select a file to upload.
          </div>
        </Dropzone>
      </div>
    );
  }
}

我的AWS政策:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::.../*"
        }
    ]
}



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

get请求成功获取signedUrl,但put请求返回错误:

Error: Network Error
    at createError (createError.js:16)
    at XMLHttpRequest.handleError (xhr.js:87)

这是建立在Next.js之上的,这给我带来了很多问题,只为客户端上传安装Cognito。

3 个答案:

答案 0 :(得分:0)

不确定问题出在哪里,但这就是我使用预签名的AWS S3链接上传文件为React工作的方式。

uploadFile (file, uploadUrl, fileKey, tags) {
    const config = { 
      headers: {
        'Content-Type': file.type,
        'x-amz-tagging': getTagging(tags)
      } 
    }
    axios.put(uploadUrl, file, config)
    .then( response => {
      console.log('file upload response', response)
      this.createDocument(file, fileKey)
    })
    .catch( e => {
      console.log('file upload ERROR:', e)
      console.log(' e.response', e.response)
      this.updateStatusOnFile(file.userInterfaceId, DOCUMENT_UPLOAD_STATUS.FAILED)
    })
  }

答案 1 :(得分:0)

在浏览器中打开signedURL并检查响应
可能的错误:

  • 终端错误:更新AWS.config.Region
  • Cors错误:在AWS s3控制台中更新,将cors添加到存储桶

答案 2 :(得分:0)

我的React应用程序中也遇到了同样的问题。然后,我使用“获取”而不是“ axios”,它运行良好。看起来很奇怪,但在我的情况下有效。

export const uploadImageS3 = (url, file) => { return fetch(
    url,
    {
        'body': file,
        'headers': {
            'Accept': 'application/json'
        },
        'method': 'PUT'
    }).then(response => {
        // Make sure the response was valid
        if (response.status >= 200 && response.status < 300) {
            return response;
        }
        const error = new Error(response.statusText);
        error.response = response;
        throw error;   
    }); 
};