'AWS S3/IAM CORS/Prefetch error when Uploading Image
I'm having problems setting up an S3 and IAM so that I can upload media files to the bucket. I've been following a video (https://www.youtube.com/watch?v=yGYeYJpRWPM&t=485s), and it feels like I've done everything that he did, but I still get a CORS error. Basically what I've done is setup an IAM account to have a "putObject" policy on my bucket, and then when the user uploads an image in the UI, I get the secured URL from the aws-sdk using my IAM credentials. Next, I then make a PUT request to the secured URL, with the file name as the Key. But that's when I get the cors error.
// frontend JS code
const form = document.querySelector("#form");
const input = document.querySelector("#file");
let url;
form.addEventListener("submit", async (e) => {
e.preventDefault();
const file = input.files[0];
if (input.files.length) {
const data = await fetch(
"https://my-bucket-name.com/api/upload-image",
{
method: "POST",
body: JSON.stringify({ fileName: input.files[0].name }),
headers: {
"Content-Type": "application/json",
},
}
);
const reponse = await data.json();
url = reponse.url;
if (url) {
const data = await fetch(url, {
method: "PUT",
body: file,
headers: {
"Content-Type": "multipart/form-data",
},
});
console.log("DATA", data);
} else {
console.log("no file");
}
}
});
// which uses this router on the express server
require("dotenv").config();
const express = require("express");
const router = express.Router();
const { s3 } = require("../../s3");
router.post("/upload-image", (req, res) => {
console.log(req.body.fileName);
s3.getSignedUrl(
"putObject",
{
Bucket: process.env.AWS_BUCKET_NAME,
Key: req.body.fileName,
Expires: 60,
},
(err, url) => {
if (err) {
console.log("\nerror", err, "\n");
return res.status(500).json({ error: err });
}
console.log("\nurl", url, "\n");
res.status(200).json({ url });
}
);
});
module.exports = router;
// the s3 file above is simply this...
require("dotenv").config();
const aws = require("aws-sdk");
const s3 = new aws.S3({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.REGION,
});
module.exports = {
s3,
};
/*Bucket Policy
{
"Version": "2012-10-17",
"Id": "policyIDNumber",
"Statement": [
{
"Sid": "bucket-sid",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
**/
/* Bucket CORS Policy
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"HEAD",
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
**/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Upload to S3 Bucket Test</title>
</head>
<body>
<form id="form" accept="image/*">
<input type="file" id="file" />
<button>Submit</button>
</form>
<script src="./index.js"></script>
</body>
</html>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|