nextjs-gcp-storage icon indicating copy to clipboard operation
nextjs-gcp-storage copied to clipboard

🐞 CORS issue 🐞 | How to use on a bucket which already exist?

Open damiano216 opened this issue 3 years ago • 3 comments

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 avatar Oct 20 '22 21:10 damiano216

@damiano216 Did you ever figure this out? I tried updating the CORS config on the bucket with no luck. It's driving me nuts

Harrisandwich avatar Nov 24 '22 22:11 Harrisandwich

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 avatar Dec 07 '22 14:12 ImBIOS

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!

jjrise avatar Feb 02 '23 00:02 jjrise