14

我正在尝试将文件从浏览器上传到 s3 amazon,我已修改 CORS 策略规则以允许发布存储桶,但出现错误

    <?xml version="1.0" encoding="UTF-8"?>
    <Error><Code>InvalidArgument</Code><Message>Bucket POST must contain a field named 'key'.  If it is specified, please check the order of the fields.</Message>
<ArgumentValue></ArgumentValue><ArgumentName>key</ArgumentName><RequestId>1E0A8DC78C0CEA9A</RequestId><HostId>XN38Qje9hUrGqHNIhtT8CtowX9tXlpyfEoaXb1UNxlsyLOWreh2mKqKVXg1zjLVl</HostId></Error>

这是我的请求和响应,我仍然收到此错误,以正确的顺序传递关键参数

http://screencast.com/t/9ZUQO0s9d

http://screencast.com/t/CL8MKq6l6

谁能告诉我有什么问题,我正在使用 FormData 提交请求

任何帮助将不胜感激。

谢谢

编辑:这是代码请检查

var form_data = new FormData();         
                form_data.append('file',hdlr.file);
                //form_data.append('crop_type',settings.get_cropped_type());
                //form_data.append('attributes',JSON.stringify(file_attr));
                $('input:hidden',$form).each(function(){

                    form_data.append(this.name,this.value);

                });


                //finally post the file through AJAX  
                var xhr = new XMLHttpRequest();  
                xhr.open("POST", $form[0].action, true);  
                xhr.send(form_data);

在此处输入图像描述

4

2 回答 2

46

看起来您的文件表单字段首先出现在请求中。我无法确定,因为您没有在答案中包含整个请求有效负载,但看起来它出现在“关键”字段的上方。AWS 会忽略请求中文件字段之后的所有字段,因此所有其他字段必须出现在文件之前。

于 2013-03-05T23:04:46.440 回答
0

谢谢雷·尼古拉斯

这个对我有用。

{
  "formAttributes": {
    "action": "https://**.s3.ap-southeast-1.amazonaws.com",
    "method": "POST",
    "enctype": "multipart/form-data"
  },
  "formInputs": {
    "acl": "public-read",
    "key": "users/2/images/drops-of-water-578897_640.jpg",
    "X-Amz-Credential": "**",
    "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
    "X-Amz-Date": "**",
    "Policy": "**",
    "X-Amz-Signature": "**"
  }
}
function uploadFile(event) {
  event.preventDefault();

  getSignedPost().then(() => {
    const fileEl = document.getElementById('id-file');
    const file = fileEl.files[0];

    const formData = new FormData();
    Object.keys(uploadCredentials.formInputs).forEach((key) => {
      formData.append(key, uploadCredentials.formInputs[key]);
    });

    // update key to file name
    const key = `users/2/images/${file.name}`;
    formData.set('key', key);
    uploadCredentials.formInputs.key = key;

    // update show data on page
    const el = document.getElementById('id-upload-info');
    el.innerText = JSON.stringify(uploadCredentials, null, 2);

    // IMPORTANCE: https://stackoverflow.com/a/15235866
    // AWS ignores all fields in the request after the file field, so all other fields must appear before the file.
    formData.append('file', file);

    fetch(uploadCredentials.formAttributes.action, {
      method: uploadCredentials.formAttributes.method,
      // headers: {
      //   'Content-Type': 'multipart/form-data',
      // },
      body: formData,
    })
      .then((res) => {
        if (res.status === 204) {
          console.log('Successfully uploaded file');
          console.log('-- 204 - no content');

          return `Successfully uploaded file: ${key}`;
        }

        if (res.ok) {
          return res.json();
        } else {
          return res.text();
        }
      })
      .then((res) => {
        alert(JSON.stringify(res, null, 2));
      })
      .catch((err) => {
        alert(err.message || err);
      });
  });
}
于 2021-08-23T17:27:25.723 回答