I have tried many configurations to get file upload with signed url. preflight request completes ok but actual upload fails with
No 'Access-Control-Allow-Origin' header is present on the requested resource.
This makes me thin that the cors config is ok but there is an issue with the way the url is being signed.
I see a lot of people having issues with this on stack overflow but no resolutions, which makes me think that this is really a documentation issue. Below is the most lenient configuration I have tried:
cors config:
[{"maxAgeSeconds": 3600, "method": ["GET", "HEAD", "POST", "PUT"], "origin": ["*"], "responseHeader": ["Content-Type", "Access-Control-Allow-Origin"]}]
serverside code:
app.post('/api/v1/upload/gcs-sign', function(req, res) {
const fileName = req.body.fileName;
const fileType = req.body.fileType;
const file = bucket.file(fileName);
// signed URL expires in 1 hour
const expirationDate = new Date(
new Date().setHours(new Date().getHours() + 1),
);
const config = {
action: 'resumable',
expires: expirationDate,
contentType: req.body.fileType,
};
file.getSignedUrl(config, (err, signedRequest) => {
if (err) {
return res.end();
}
res.json({ signedRequest });
res.end();
})
client side code:
uploadToGCS = (signedRequest, file) => {
let xhr = new XMLHttpRequest();
xhr.open('POST', signedRequest);
xhr.onload = () => {
this.onUploadFinish(xhr);
};
xhr.onerror = this.onUploadError;
xhr.upload.onprogress = this.onUploadProgress;
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);
};
@google-cloud/storage version: 1.7.0Thanks!
Follow up:
to be more clear, this issue is really a development issue. I am running a node server from localhost:5000 for my backend, and then serving a react app from localhost:8080. If I serve the pre built react app from the node server then everything is fine, but if I want to run a development server, which does hot reloads and therefore makes life much easier for me, I just cant get the CORS issues to go away. I can manually set an origin for resumable url creation, but not for signed urls.
An optional workaround is to setup the HMR to work with the node server.
With vue.js it can be done very easily in 3 simple steps as you can read here
I guess it can be done in a similar way for React too.
@joshyg Thanks for reporting this. We just released Storage 2.0. Would you mind checking if this is still an issue? 馃檹
"@google-cloud/storage": "^2.5.0",
When set a PUT request, got 403 CORS issue
Access to fetch at 'https://storage.googleapis.com/ez2on/adminUsers.png?GoogleAccessId=cloud-storage-admin%40shadowsocks-218808.iam.gserviceaccount.com&Expires=1562828722&Signature=Ct8csNNzidof5bglywdhRWNJe7gHijxho1Tlnvyr0L1zbdxqlkGJRY33bUe%2BkM3GnfywyIuOwBeUwazVrATvXpWnDItYrOUOdGWC7s6v9VJhfDH5dNBQraV%2F3%2FYGeENQLKh%2B%2BSsNUNCd7wezUUeKrz1f2ht%2B5QognE1Zlctwl%2FEApnLLLFqCwY%2FHZ3rwVuhlee6hLxJn3SMqggkmDMJjHxUotShBOBmHSBF6oecwgKVOsxEdwuu2cyU2FpfBfeXUe%2F26PJVIiWwvl5%2F56Qlf6P32zyWPGKoVEoXEwxagqvF3iyuPrdp0hR8pOUzPgJurwEkvgHbSuOfWq%2BojBoJifg%3D%3D' 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.
I do have the same issue as you do @mrdulin
For more details about mine :
Preflight OPTIONS request responds ok with the correct headers, and then my PUT request got 403 too
@sebght Try change version option for getSignedUrl method from v2(default) to v4
Quite surprisingly, adding "Content-Type": file.type removed the CORS issue with my case 馃槃
Hi, sorry for reopen this issue, i had same issue.
In my request i have to add Content-Type header when PUT method, but the cors still appear.
can you help me?
Greetings! If you're having issues, would you mind opening a new issue? It can be hard to find and track these when they're closed :)
@sebght Try change
versionoption forgetSignedUrlmethod fromv2(default) tov4
This made the difference for me. There's clearly an issue with v2 and CORS. As soon as I switched to v4 the same CORS settings worked fine.
When I try to use v4 I get an unknown error! How do I change it? Getting 403 even with CORS file defined with: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], "origin": ["*"], "responseHeader": ["Content-Type", "Authorization", "Content-Length", "User-Agent", "x-goog-resumable", "Access-Control-Allow-Origin"]}]...
Now it works... I was using POST instead of PUT and I had to set the Content-Type on both the getSignedURL config and the client's POST request header. I could get it working using Content-Type to 'application/octet-stream'.
If someone happens to fall into this Closed Issue, chrome was giving me 403 but the response had a message saying "The request signature we calculated does not match the signature you provided.", I suggest using Postman to improve debugging...
Now it works... I was using POST instead of PUT and I had to set the Content-Type on both the getSignedURL config and the client's POST request header. I could get it working using Content-Type to 'application/octet-stream'.
THANK YOU!!!! Fought with this for DAYS. Setting the content type to application/octet-stream in both parts did the trick!
EDIT: changing it to the file type also worked (and still works with my firebase auto-resize extension)!
I was using fetch with FormData to send the file, for whatever reason that did not work. I ended up doing a couple of things:
After doing all of those I finally have it working.
Most helpful comment
@sebght Try change
versionoption forgetSignedUrlmethod fromv2(default) tov4