🐞 CORS issue 🐞 | How to use on a bucket which already exist?
Hello, first of all thanks for this tutorial! It was really helpful as I couldn't find much information on how to use google cloud storage with Nextjs elsewhere online .
I already have a google cloud storage bucket aka "my-bucket-name", so I am trying to adapt your code to use my existing bucket instead of creating a new one when the codebase starts.
However, I am clearly doing something wrong 🐞🐞🐞 since on localhost:3000 I keep getting the error :
Access to fetch at 'https://storage.googleapis.com/my-bucket-name/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. as I was wondering whether someone here could help.
This is my cors.config.json file:
[ { "origin": ["*"], "method": ["POST", "GET"], "responseHeader": [ "Content-Type", "access-control-allow-origin", "access-control-allow-header" ], "maxAgeSeconds": 3600 } ]
Which I setup by running the command:
gsutil cors set cors.config.json gs://my-bucket-name
as per google documentation. When I run
gsutil cors get gs://my-bucket-name
the cors config correctly prints out. So far so good 👍
In my frontend I am getting an input file from a classic HTML <input type="file" ... /> which then I pass down to my Nextjs api route like this:
try {
const filename = encodeURIComponent(inputFile.name);
const res = await fetch(
`/api/upload-file-in-cloud-storage?file=${filename}`
);
const { url, fields } = await res.json();
const formData = new FormData();
Object.entries({ ...fields, inputFile }).forEach(([key, value]) => {
formData.append(key, value);
});
const upload = await fetch(url, {
method: "POST",
body: formData,
});
if (upload.ok) {
console.log("Uploaded successfully!");
} else {
console.error("Upload failed.");
}
} catch (err) {
console.log("err", err);
}
My /api/upload-file-in-cloud-storage nextjs API route consist of:
import { Storage } from "@google-cloud/storage";
export default async function handler(req, res) {
const storage = new Storage({
projectId: process.env.GCLOUD_PROJECT_ID,
credentials: {
client_email: process.env.GCLOUD_CLIENT_EMAIL,
private_key: process.env.GCLOUD_PRIVATE_KEY,
},
});
const bucket = storage.bucket(process.env.GCLOUD_STORAGE_BUCKET);
const file = bucket.file(req.query.file);
const options = {
expires: Date.now() + 1 * 60 * 1000, // 1 minute,
fields: { "x-goog-meta-test": "data" },
};
const [response] = await file.generateSignedPostPolicyV4(options);
res.status(200).json(response);
}
If in the above API route I console.log("bucket", bucket) I get my existing bucket name etc, so I can access it. However, I could never get the input file uploaded to it.
Despite waiting some hours for the CORS policy to apply and googling the issue, I can't get past it. Perhaps someone here did solve this case before? If so, could you please help me? Thanks very much
@damiano216 Did you ever figure this out? I tried updating the CORS config on the bucket with no luck. It's driving me nuts
Create a CORS configuration file cors.json
[
{
"origin": ["*"],
"method": ["*"],
"responseHeader": ["*"],
"maxAgeSeconds": 3600
}
]
Then, execute this command:
gcloud storage buckets update gs://BUCKET_NAME --cors-file="cors.json"
And make sure the configuration is correct by executing:
gcloud storage buckets describe gs://BUCKET_NAME --format="default(cors)"
Create a CORS configuration file
cors.json[ { "origin": ["*"], "method": ["*"], "responseHeader": ["*"], "maxAgeSeconds": 3600 } ]Then, execute this command:
gcloud storage buckets update gs://BUCKET_NAME --cors-file="cors.json"And make sure the configuration is correct by executing:
gcloud storage buckets describe gs://BUCKET_NAME --format="default(cors)"
@ImBIOS you are the best! thanks for that!