I am using the javascript API.
I am trying to use a signed url to upload a file to my Google Cloud Storage. The code to create the signed url is this:
// args have name of file and type
// config has information about the bucket, etc
const uploadOptions = {
destination: args.name,
};
console.log(`Content-Type: ${args.fileType}`)
const signingOptions = {
version: "v4",
action: "write",
expires: Date.now() + 15*60*1000,
contentType: args.fileType,
};
const response = Promise.await(myStorage.bucket(config.bucketName).file(args.name, uploadOptions).getSignedUrl(signingOptions));
return response;
I then use this url to try to upload the file with fetch thus:
// writeUrl is the url created by the above code
fetch(writeUrl,
{method: "PUT",
origin: "https:localhost:3000",
headers: {"content-type": fileElement.files[0].type},
body: fileElement.files[0]})
.then((response) => {
// Do something
})
.catch((error) => {
console.log(error);
})
This fails. The url returns an error message from the server that looks like this:
<Error> <Code>MalformedSecurityHeader</Code> <Message>Invalid argument.</Message> <Details>Your request has a malformed header. Header was included in signedheaders, but not in the request.</Details> <ParameterName>content-type</ParameterName> </Error>
This appears to be telling me I did not include a header "content-type". However, I think I did. I looked at Chrome's network tab to verify, and it says this:
Content-Type: image/png
Referer: http://localhost:3000/
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
However, Chrome also says that this is "provisional", as it might have come from the cache or from a failed request. It certainly came from a failed request, but the caching off box is checked in the Chrome network tab.
I am at a loss. It appears as though some comparison was case-sensitive and returned a mismatch erroneously. But that doesn't seem very plausible, since headers are supposed to be case insensitive, and this kind of functionality gets used every day successfully.
Help? Thoughts?
I have figured out what's going on here. It was my mistake. I misinterpreted some things that the browser was telling me, and I thought I would share my error because it might help someone else at some point.
What I was seeing was a failure of a CORS preflight request. This was due to a misconfiguration of the CORS response on my server.
However, when I looked in Chrome's Network tab, it does not show me the preflight request at all. So I wasn't aware that it was happening let alone looking at it to see what was wrong.
And then, not knowing this, I clicked on the link in the Chrome console that corresponded to the (signed) URL I was trying to PUT to. This got a response that didn't depend on CORS, it seems. It also didn't add the "content-type" header, because I just clicked on a link. So that's why that error showed up.
So, in the end, I was doing two different things and thinking they were the same thing. Confusion abouts.
With that insight, I fixed the CORS misconfiguration and it works now.