0

I am trying to create a react app where a user can upload a file to an S3 bucket.

I have a react component that can successfully get the file from the user. And a button that calls a function where I can send the file to S3.

I am using react-aws-s3 because this is going to be the only direct functionality I am going to need so I didn't want to install the whole aws-sdk package and bloat my application.

Now I have followed a few different blogs/instructions on how to do this (like this one) but haven't been able to get the file to upload.

My upload code looks like this (and I will be moving the access keys to env variables):

const S3_BUCKET = ...
const REGION = ...
const ACCESS_KEY = ...
const SECRET_ACCESS_KEY = ...

const config = {
    bucketName: S3_BUCKET,
    region: REGION,
    accessKeyId: ACCESS_KEY,
    secretAccessKey: SECRET_ACCESS_KEY,
};

const ReactS3Client = new S3(config);
// the name of the file uploaded is used to upload it to S3
ReactS3Client.uploadFile(datasheet, datasheet.name)
    .then((data) => console.log(data.location))
    .catch((err) => console.error(err));

I have enabled public access, added the bucket policy to this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicListGet",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:List*",
                "s3:Get*"
            ],
            "Resource": [
                "arn:aws:s3::: my bucket name",
                "arn:aws:s3::: my bucket name/*"
            ]
        }
    ]
}

and the cors policy to this:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2",
            "ETag"
        ]
    }
]

But when I try and upload the file I get a 400 bad request response.

body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 400
statusText: "Bad Request"
type: "cors"
url: ...
[[Prototype]]: Response

It says it's type: cors but I have cors fully enabled right? What am I missing here?

1 Answer 1

1

When I followed the tutorial that you pasted I managed to upload the file to s3. It works with your cors policy as well. Here are a couple of things to check:

  1. The network tab and the actual response from S3 enter image description here This will give you more information on the actual problem that you are having
  1. Your bucket policy allows only List and Get, but in the tutorial, it's s3:* So your user must have permission to upload files to this bucket.

  2. Double check the upload logic in the demo it's like this:

    const handleFileInput = (e) => {
        setSelectedFile(e.target.files[0]);
    }

    const uploadFile = async (file) => {
        const ReactS3Client = new S3(config);
        // the name of the file uploaded is used to upload it to S3
        ReactS3Client
        .uploadFile(file, file.name)
        .then(data => console.log(data.location))
        .catch(err => console.error(err))
    }
    return <div>
        <div>React S3 File Upload</div>
        <input type="file" onChange={handleFileInput}/>
        <br></br>
        <button onClick={() => uploadFile(selectedFile)}> Upload to S3</button>
    </div>
Sign up to request clarification or add additional context in comments.

4 Comments

I was using a service class for my upload call functionality. I tried just doing it in the component like you have, but still get the same problem. So I decided to delete and recreate the S3 bucket. I added the bucket and cors policies, made it public access, and now I'm getting Access to fetch at '....amazonaws.com/' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Never mind. Looks like the updated cors policy need like a half hour to catch up. I tried it again and just get the same error as before.
Also, I am using the access keys for the IAM user that I used to create the bucket so I assume I have a write accessibility?
I feel a bit silly now. I thought I had ACLs enabled. Enabling that fixed everything. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.