1
votes

I have a signedURL for a google cloud storage bucket, and I want to use it with axios to make a PUT request.

My putFileData function is called when the variable signedURL is not empty, via useEffect.

  const putFileData = async () => {
    await axios
    .put(signedURL, "HELLO TXT!!!!")
    .then((response) => console.log(response))
    .catch(err => {console.log("AXIOS ERROR: ", err)})  
}

I set the CORS policy on the bucket with a json file, and when I query the bucket's cors policy I get:

[{"maxAgeSeconds": 360, "method": ["PUT"], "origin": ["http://localhost:3000"], "responseHeader": ["Content-Type"]}]

The options on my signedURL are:

const options = {
  version: 'v4',
  action: 'write',
  expires: Date.now() + 15 * 60 * 1000, // 15 minutes
  contentType: 'application/octet-stream',
};

Yet I still can't do the PUT request from http://localhost:3000.

I get:

Access to XMLHttpRequest at 'mysignedurl' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

and:

PUT mysignedurl::ERR_FAILED

In my Network tab of Chrome Developer tools it shows the request is made twice - first unsuccessfully with status 403, then successfully with status 200 - yet nothing is uploaded to the bucket.

My signed url is generated with this function in my Cloud Functions:

async function generateV4UploadSignedUrl(bucketName, fileName) {
// These options will allow temporary uploading of the file with outgoing
// Content-Type: application/octet-stream header.
const options = {
  version: 'v4',
  action: 'write',
  expires: Date.now() + 15 * 60 * 1000, // 15 minutes
  contentType: 'application/octet-stream',
};

// Get a v4 signed URL for uploading file
const [url] = await storage
  .bucket(bucketName)
  .file(fileName)
  .getSignedUrl(options)
  
return url;

};

1
Could you please share how are you creating your signed URL ? Could you please add the response header as following : "responseHeader": ["Content-Type", "access-control-allow-origin"]}] and check if you still get the error?Nibrass H
I did amend the responseHeader and I've added the function that generates my signedUrl.Davtho1983
The signedUrl I get back is one that starts storage.googleapis.com/mybucket and that is the JSON Api upload and it seems that doesn't accept CORS, cloud.google.com/storage/docs/request-endpoints#xml-api but that is the url the signedURL function returns? Is there a way to generate an XML signedURL?Davtho1983
I have exactly the same code but still getting this error no matter what I try :-/Oliver Dixon
Check the IAM Permissions - I found it just gives CORS errors as a sort of general error - it's not that helpful for diagnosing the actual issue.Davtho1983

1 Answers

1
votes

With the help of the Google Cloud Support team, I figured out the ContentType was incorrect. I changed the options to:

contentType: 'application/x-www-form-urlencoded',

and it worked!