Giter Site home page Giter Site logo

Comments (49)

hendrikfrentrup avatar hendrikfrentrup commented on September 22, 2024 6

This issue is closed pre-maturely and it looks to me the issue lies with Google's backend - not Chrome or anything else.

Here is why:
CORS is a browser security feature hence the issue arises with AJAX requests. The objective for most will be to upload a fairly large file to a Google Storage bucket directly without going through an app server. The app server is used to provide the signed URL to upload directly to the GS bucket, akin to the initial POST request described in Google's docs here. The app server generates the signed URL via Google's API and returns it to the client.

This is when the crucial part of the upload starts. The docs describe a PUT request via curl - but most apps run in a browser so we create an AJAX PUT request (Content-Length is by default populated by the browser).

let file = $("#file-input")[0].files[0]
fetch(<signed_url>,
    {
        method: 'PUT',
        body: file
    })

Now CORS kicks in, so I've set the following CORS configuration on the bucket:

[
  {
    "origin": ["*"],
    "method": ["PUT", "OPTIONS"],
    "responseHeader": [
        "Content-Type",
        "Access-Control-Allow-Origin"
    ],
    "maxAgeSeconds": 60
  }
]

It sends a preflight request (method: OPTIONS) - as per specification it contains the origin header, e.g. for something running locally: origin: http://localhost:8080. This preflight request is successful and returns with status 200 and the following headers:

access-control-allow-headers : content-type
access-control-allow-methods : PUT

Then, the actual PUT request gets fired off. The crucial point is that this request also runs successfully and returns with status 200 (the payload is also saved to the bucket!) BUT the response does not contain the Access-Control-Allow-Origin header. And that is what the browser is expecting according to the specs. The browser therefore drops the response payload and throws the error.

I would expect that if I specifically set my CORS config for origin via gsutil (see GCS docs) to '*' or a specific domain (http://localhost:8080 should also work!), then the response from the GCS bucket would include it in its response header. For example, a request fired off from a script hosted at myapp.appspot.com would pass CORS when the domain is included in the origin value of the configuration.

What do the folks at Google think about this? Might someone have mocked around with the headers that get sent back? CORS is a security feature, so it should work well and specs should be adhered to (especially when they are described in detail in your docs).

from python-storage.

danjenson avatar danjenson commented on September 22, 2024 2

This fails from a browser. It's the same issue. Before it submits the POST request to the signed URL, it submits a preflight OPTIONS request, which does not return Access-Control-Allow-Origin headers, so it abandons the POST request to start the resumable upload. This is only an in-browser issue due to modern browsers' CORS policies. Uploading and downloading work fine outside of the browser with js, python, and command line. If you run that nodejs code from the browser, it will block it due to the preflight OPTIONS request.

Restated: you are hosting your website on web.appspot.com, which delivers the website payload. Now, in that website, there is code like you posted above. However, the host there is storage.googleapis.com, which is not web.appspot.com. So, the browser checks to see if it's ok to make a cross origin request, and so issues an OPTIONS request to the bucket on storage.googleapis.com. The problem is that the OPTIONS response is not returning Access-Control-Allow-Origin header, which it requires so it can check that the current host is in that list. If it's in the list, it will proceed with the POST/PUT, if not (or if the header is absent as in this case), it cancels future requests due to the CORS policy. That, I believe, is what is happening here, and it is unique to the browser, so isolated nodejs/python/etc code will not reproduce it (since none of those make or validate preflight OPTIONS requests).

According to this document: https://cloud.google.com/storage/docs/configuring-cors#troubleshooting, the server should be returning the Access-Control-Allow-Origin in the OPTIONS response, but it is not.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024 2

Out of curiosity, why was this downgraded? Seems like being able to upload a file to cloud storage from a browser is a pretty important use case? Right now we're switching to flexible instances on app engine so we can increase the memory so users can upload to the server and then we upload from the server to storage. This is clearly not ideal and will probably cost us a non trivial amount since our users could be uploading up to 10gb files (which we'd rather have go straight to storage).

from python-storage.

kikoanis avatar kikoanis commented on September 22, 2024 2

After spending few hours on the cors issue, here is what worked for me.

Google Storage Server CORS settings:

     "origin": [<your origins>],
     "responseHeader": ["Content-Type", "Access-Control-Allow-Origin", "X-Requested-With", "x-goog-resumable"],
     "method": ["PUT", "POST"],
     "maxAgeSeconds": 3600

Do not include any thing in your request other than the file buffer/stream in the put signed url request. No authorization header nor any other headers, only the content type (which is file type 'image/jpeg' for images for instance).
Every time you make a change, you need to clear browser cache. That is essential as you may get a previous response.

As chrome is no longer providing access to the options preflight request, you may need to use tools like fiddler or http toolkit to inspect the options preflight response. If the options response does not include Access-Control-Allow-Origin header, it means something not right in your request. Try to correct/use other options till you see that header in the preflight response.

Hope this helps.

from python-storage.

jfbrennan avatar jfbrennan commented on September 22, 2024 2

Had this issue and like @mlescaudron has shown, it's because Chrome is swallowing up the actual response and logging a somewhat misleading error about CORS.

I say somewhat misleading because it appears the error response does not have the proper CORS headers even though they've been properly set via gsutil. In my case I did not know about the need to send a x-goog-content-sha256 header in the request (and whitelist it in my CORS config). Once I did that, the request was successful. Removing that header from the request and it goes right back to the misleading CORS error in Chrome.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024 1

@danjenson The sample code which use Axios npm package, it would be helpful if you have missed something.

Please Verify:

bucket.cors = [
 {
  "origin": ["*"],
  "responseHeader": [
    "Content-Type",
    "Access-Control-Allow-Origin",
    "x-goog-resumable"],
  "method": [PUT', 'POST'],
  "maxAgeSeconds": 3600
 }
]

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024 1

Do I need to add 'resumable' somehow in the python side that creates the signed URL?

Yes you need to add resumable, The steps to create signurl and upload blob are following if you are using only python:

from google.cloud import storage 
import requests 
client = storage.Client()   
bucket = client.get_bucket('bucket')
blob = bucket.get_blob('blob_name')

url = blob.generate_signed_url(expiration=3600,method="RESUMABLE",client=client,version='v4' )  # generate sign url

post_headers = {"x-goog-resumable": "start"}
post_response = requests.post(url, headers=post_headers)

payload = b"DEADBEEF"
location = post_response.headers["Location"] 
put_headers = {"content-length": str(len(payload))} 
put_response = requests.put(location, headers=put_headers, data=payload)

from python-storage.

jkwlui avatar jkwlui commented on September 22, 2024 1

A shorted update - I've reached out to the service team since it appears to me this could have been a backend issue with the bad preflight request. I'll respond once we got a response from them.

@danjenson We're sorry for the delay and I appreciate your patience while we work to resolve this.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

related issues in google-cloud-nodejs-storage 245, 347 which has been closed.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

I have confirmed those cors settings. Still getting a failed preflight OPTIONS check. Do I need to add 'resumable' somehow in the python side that creates the signed URL? This is how the signed URIs are currently being created: https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers#storage-signed-url-object-python

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

I also just tried the changing the endpoint to the JSON API as well as the dedicated XML API endpoints listed here: https://cloud.google.com/storage/docs/request-endpoints. I couldn't get those to work at all (404 or Invalid Signature errors), although I messed around far less than with the default endpoint.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

According to this https://cloud.google.com/storage/docs/cross-origin it looks like the preflight is just not returning the correct headers; here is the preflight OPTIONS request my browser, Chrome 79, automatically made:

:authority: storage.googleapis.com
:method: OPTIONS
:path: <removed for security>
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,it-IT;q=0.6,it;q=0.5,es-US;q=0.4,es;q=0.3
access-control-request-headers: content-type
access-control-request-method: PUT
origin: http://localhost:8080
referer: http://localhost:8080/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4033.2 Safari/537.36
x-client-data: CJO2yQEIo7bJAQisncoBCNCvygEI/K/KAQiesMoBCL2wygEImbLKAQiLtMoBCJa1ygEI7bXKAQiAtsoBCL22ygEIjbrKAQjku8oBCPq7ygEIk73KAQiavcoBGKukygEYy7HKARiks8oBGLW6ygE=

And here is the response:

alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
cache-control: private, max-age=0
content-length: 0
content-type: text/html; charset=UTF-8
date: Thu, 30 Jan 2020 18:27:00 GMT
expires: Thu, 30 Jan 2020 18:27:00 GMT
server: UploadServer
status: 200
vary: Origin
x-guploader-uploadid: AEnB2UqAGBxk5OUQkg6FNngMcRw4Y-vloQaEpMw4QFk2mLmZwiOf6p-0O-JPCiCW9l0jS22MvNWHdL5E0hOgyKoOuXpuD3eT_g

And the chrome console error:

Access to fetch at 'https://storage.googleapis.com/<removed for security>' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

Again, the signed url is valid, because I can PUT a file using curl from command line.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

It appears fetch populates the list of headers for access-control-request-headers in OPTIONS requests by inspecting the headers in the original request, so I modified my fetch to be the following:

# uploadUri is a signed uri from the 'test' bucket for uploading (PUT requests, v4)
# file is a local filesystem file
fetch(uploadUri, {
  method: 'PUT',
  mode: 'cors',
  cache: 'no-cache',
  headers: {
    'Content-Type': 'application/octet-stream', 
    'Access-Control-Allow-Origin': '*'  # <============== NEW
  },
  body: file,
}).then(() => console.log('success'));

This creates the OPTIONS request:

:authority: storage.googleapis.com
:method: OPTIONS
:path: <removed for security>
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,it-IT;q=0.6,it;q=0.5,es-US;q=0.4,es;q=0.3
access-control-request-headers: access-control-allow-origin,content-type  # <====== UPDATED
access-control-request-method: PUT
origin: http://localhost:8080
referer: http://localhost:8080/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4033.2 Safari/537.36
x-client-data: CJO2yQEIo7bJAQisncoBCNCvygEI/K/KAQiesMoBCL2wygEImbLKAQiLtMoBCJa1ygEI7bXKAQiAtsoBCL22ygEIjbrKAQjku8oBCPq7ygEIk73KAQiavcoBGKukygEYy7HKARiks8oBGLW6ygE=

So you can see it is explicitly asking for access-control-allow-origin, content-type headers; it specifies origin and also sets sec-fetch-mode to cors. Yet the response still does not return Access-Control-Allow-Origin:

alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
cache-control: private, max-age=0
content-length: 0
content-type: text/html; charset=UTF-8
date: Thu, 30 Jan 2020 19:22:09 GMT
expires: Thu, 30 Jan 2020 19:22:09 GMT
server: UploadServer
status: 200
vary: Origin
x-guploader-uploadid: AEnB2Uo3FX_dqZ0wVqp5bMoV0xMY2BJ6IEPjLXlAEDM0jYgC01DLs8umt7wjI_PPbIz4C_m3Mmhmf-o6FmSnNM3OwjUAwXGq9A

For fun:

$ gsutil cors get gs://test
[{"origin": ["*"]},{"responseHeader": ["Content-Type", "Access-Control-Allow-Origin", "x-goog-resumable"]},{"method": ["PUT", "POST", "GET"]},{"maxAgeSeconds": 3600}]

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

curl -I -X OPTIONS -H 'Access-Control-Request-Headers: Access-Control-Allow-Origin,Content-Type' <signed_url> returns the same headers as in the browser (i.e. doesn't return Access-Control-Allow-Origin header).

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Signing a URL using gsutil with gsutil signurl -c 'application/octet-stream' -d 1 -m PUT service_account.json gs://test/test.csv and then calling the above command also does not return the correct OPTIONS headers. The CORS issue also happens in Firefox 72.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Does this work from a browser though? I have no problem just making a put request with the signed url from python or command line (without resumable). The problem was the CORS policy in the browser. And the fact that the OPTIONS response didn't return the Access-Control-Allow-Origin header, so the PUT failed from the browser.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

Need to pass resumable when creating a signed url like:

url = blob.generate_signed_url(expiration=3600,method="RESUMABLE",client=client,version='v4' )  # generate sign url

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

Here is the code which works with flask and nodejs as you have used:

Flask code:

from datetime import datetime, timedelta
from flask import Flask
from flask import abort
from google.cloud import storage
from flask import request

app = Flask(__name__)

@app.route('/', methods=['POST'])
def function():

    if request.method != 'POST':
        return abort(405)

request_json = request.get_json()
client = storage.Client()

# Get a reference to the destination file in GCS
bucket_name = request_json['bucket']
file_name = request_json['filename']
bucket = client.get_bucket(bucket_name) 
file = bucket.blob(file_name)

# Create a temporary upload URL
expires_at_ms = datetime.now() + timedelta(seconds=30)
url = file.generate_signed_url(expires_at_ms,
                               version='v4',
                               method="RESUMABLE")

return {'signed_url': url}, 200

Nodejs code:

const axios = require('axios')

url = 'http://127.0.0.1:5000/'
axios.post(url, { bucket: "test-hemang-bucket", filename: "hello.txt"}) 
.then((response) => {   
const options = {
    headers: {"x-goog-resumable": "start"}
 };
 axios.post(response.data.signed_url, {},options)
 .then(axiosResponse => {     // make sure axiosResponse.status = 201
     axios.put(axiosResponse.headers.location, "Hello There!",{headers: {"Content-Type": 
   "text/plain", 'Content-Length': 12}}).then(postResponse => {
         console.log("success : ", postResponse);
    }).catch(error => {
          console.log("put : ", error);
   });
   }).catch(error => {
         console.log("post : ", error);
        return "";
  }).catch(err => console.warn(err));
  }).catch(error => {
        console.log("errorSubmitImage : ", error);
 });

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@danjenson sorry for the mess, surely this will help you please visit this link.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@crwilcox Please comment on this, For the OPTIONS request , backend should return the Access-Control-Origin header or what i share a link is the only option to handle cors.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

It looks like that link is for Cloud Functions? I'm using App Engine to host my website, and Cloud Storage to store content. My problem is the prefight OPTIONS response on the bucket; I'm using the instructions here: https://googleapis.dev/python/storage/latest/buckets.html (search for 'cors') to set CORS on my bucket, and when I use gsutil, they show the correct CORS options...I'm just not getting the right headers in the OPTIONS response.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@crwilcox This is back-end issue,so can you filed issue as internal issue.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Is there any chance this will be resolved in the next few weeks? We're a team a Stanford that is planning on releasing a platform for data journalism next month at our big conference. However, a key element of that is having users be able to upload large datasets from the website (in a browser with a CORS policy). If it's unlikely this will be resolved, we need to investigate other platforms.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

@HemangChothani, any word?

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@frankyn @crwilcox could you please comment or any suggestion.

from python-storage.

frankyn avatar frankyn commented on September 22, 2024

Hi folks,

Thanks for the ping @HemangChothani.

I reviewed the Storage documentation. I have a short question while I dig into this as nothing stands out right now.

In documentation:

If you're not seeing a request and response, it is possible that your browser has cached an earlier failed preflight request attempt. Clearing your browser's cache should also clear the preflight cache.

Have you attempted to clear your browser cache @danjenson? I understand that cache-control is private and maxAge is 0.
Apologies if this is not very helpful but I'm taking a look and want to make sure this isn't the case.

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Yes, countless times. I also used incognito since it shouldn't store that information

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Any progress on this?

from python-storage.

frankyn avatar frankyn commented on September 22, 2024

Bumping priority on this. It's in my queue but don't have an update at this time apologies for the delay @danjenson.

@jkwlui could you take a look at this issue?

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Has this been remedied? I still can't manage to pull down a file with our a CORS error.

from python-storage.

frankyn avatar frankyn commented on September 22, 2024

Hi @danjenson, it's a work in progress and we are speaking with the service team. We appreciate your patience.

from python-storage.

jkwlui avatar jkwlui commented on September 22, 2024

@danjenson Can you try adding "responseHeader": ["*"] to your bucket's CORS config?

from python-storage.

AnuroopSuresh avatar AnuroopSuresh commented on September 22, 2024

hello, facing the same issue. 'gsutil cors get gs://...' output:

[{"maxAgeSeconds": 3600, "method": ["*"], "origin": ["*"], "responseHeader": ["*"]}]

my NodeJs Code:

async function generateV4UploadSignedUrl(filename, mimeType, expiryInMs) {
    // 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() + 1000 * 60 * expiryInMins, // 15 minutes
        expires: expiryInMs,
        contentType: mimeType,
    };

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

    console.log(`curl -X PUT -H 'Content-Type: ${mimeType}' --upload-file ${filename} '${url}'`);
    return url;
}

browser response:

alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,h3-T050=":443"; ma=2592000
cache-control: private, max-age=0
content-length: 267
content-type: application/xml; charset=UTF-8
date: Fri, 03 Apr 2020 08:23:57 GMT
expires: Fri, 03 Apr 2020 08:23:57 GMT
server: UploadServer
status: 400
x-guploader-uploadid: AEnB2UqUuAZ-giq_ljMBwLrXNN5SRZHKwb12jI-uhhXU4oXczdEzjnZLjyOxXS3pQxYb3dUWG508_jui--wrM4xAnjQhGT33Mg

No. Access-control-allow-origin header. Plz any update. ??

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Same, any update? This is taking quite a while for a p1 bug. We can't load anything on our domain/website directly from storage due to this issue.

from python-storage.

jkwlui avatar jkwlui commented on September 22, 2024

Hi, @danjenson. Again we apologize for the delay. If this is a PUT request, you shouldn't need to deal with resumable headers.

Here's a set of steps that worked for me:

[{
        "origin": [
                "*"
        ],
        "responseHeader": [
                "Content-Type",
                "x-goog-resumable"
        ],
        "method": [
                "PUT",
                "POST"
        ],
        "maxAgeSeconds": 3600
}]
$  gsutil cors set cors.json gs://bucket-name

generate_signed_url.py

import datetime
import sys
from google.cloud import storage

bucket_name = sys.argv[1]

store = storage.Client()
bucket = store.bucket(bucket_name)
blob = bucket.blob('test.txt')
signed_url = blob.generate_signed_url(expiration=datetime.timedelta(days=1), version='v4',scheme='https',method='PUT')

cmd = 'curl -v -i -X OPTIONS -H "Origin: hello.com" -H "Access-Control-Request-Method: PUT" -H "Access-Control-Request-Headers: Content-Type" {}'.format(signed_url)

print(cmd)

Then run python generate_signed_url.py <bucket-name>, which returns a curl command that makes an OPTIONS request. Run the curl command.

curl returns CORS response headers as expected:

< access-control-allow-methods: PUT,POST
access-control-allow-methods: PUT,POST
< access-control-allow-headers: Content-Type,x-goog-resumable
access-control-allow-headers: Content-Type,x-goog-resumable

Using the signed URL in the browser with the Fetch API also worked for me:

<script>
const url = '<insert signed url from python script>';
fetch(url, {
    method: 'PUT',
});
</script>

Screen Shot 2020-04-09 at 5 32 15 PM

from python-storage.

dharanidhar-reddy avatar dharanidhar-reddy commented on September 22, 2024

Hi @jkwlui, Do you have any update on the issue? We are also facing it.
gsutil cors get gs://...
[{"maxAgeSeconds": 3600, "method": ["PUT"], "origin": ["*"], "responseHeader": ["Authorization", "Content-Range", "Accept", "Content-Type", "Origin", "Range"]}]
This worked for some time.

Screenshot from 2020-04-16 19-29-05

But now we are not even getting the configured response headers.

Screenshot from 2020-04-21 22-37-32

from python-storage.

jkwlui avatar jkwlui commented on September 22, 2024

@dharanidhar-reddy Thanks for the additional information. One question - do you have an estimate of how long did it work until it failed again?

from python-storage.

dharanidhar-reddy avatar dharanidhar-reddy commented on September 22, 2024

@dharanidhar-reddy Thanks for the additional information. One question - do you have an estimate of how long did it work until it failed again?

I'm not really sure about how much time it worked. It worked on APR 16 and we checked a couple of hours ago and it didn't work.

from python-storage.

kilianstallz avatar kilianstallz commented on September 22, 2024

Same issue here, @danjenson

So we too generate a signed url using our backend API like this:

const [url] = await this.storage.bucket(bucketName).file(filename).getSignedUrl({
            action: 'write',
            version: 'v4',
            contentType: filetype,
            expires: Date.now() + 15 * 60 * 1000, // 15minutes
        })

we are using this CORS policy for testing purposes:

[{"origin": ["*"],"responseHeader": ["*"],"method": ["*"],"maxAgeSeconds": 3600}]

This did not work using the browsers Fetch API, we switched to simple XHR-Requests like this:

const signedURL = getSingedURL()
const xhr = new XMLHttpRequest()
    xhr.open('PUT', signedURL, true)
    xhr.onload = () => {
      const status = xhr.status
      if (status === 200) {
        console.log('uploaded')
      } else {
        alert('WRONG!')
      }
    }
    xhr.onerror = () => {
      alert('ERROR')
    }
    xhr.setRequestHeader('Content-Type', this.file?.type as string)
    xhr.send(this.file)

works perfectly for us!

from python-storage.

BrandonY avatar BrandonY commented on September 22, 2024

I have been trying to reproduce this problem but have so far been been unsuccessful. All of the CORS preflight requests I've tried have returned correct CORS headers (or not, should the request not be acceptable according to the bucket's policy). There can be up to a 30 second delay while new CORS policies propagate, which is expected, but asides from that I haven't seen any oddities.

Can anyone who still sees it either provide careful reproduction steps or perhaps a fairly long-lived signed URL that I could try invoking?

from python-storage.

AnuroopSuresh avatar AnuroopSuresh commented on September 22, 2024
[
  {
    "origin": ["<yourOrigin>"],
    "method": ["OPTIONS", "PUT"],
    "responseHeader": [
      "Content-Type",
      "Access-Control-Allow-Origin",
      "X-Requested-With"
    ],
    "maxAgeSeconds": 3600
  }
] 

Please try with this CORS header

googleapis/nodejs-storage#1145

it worked for me

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@danjenson Could please confirm that given solution from AnuroopSuresh is working for you or not .
It worked for me as well.

from python-storage.

govindrai avatar govindrai commented on September 22, 2024

@danjenson I dunno if this will help, but I ran into this and spent about 6 hours on it. Here's what was happening for me:

I tried to upload an image with a signed url. That request would return a CORS error in Chrome devtools stating that dreaded no "ACCESS_CONTROL_ALLOW_METHODS" headers were present... Since Chrome has taken out OPTIONS requests visibility on chrome 79+, I used a tool called HTTP Toolkit tool to intercept look at exactly what the OPTIONS request was returning. The options request was, in fact, returning the right headers, however, the signed request was returning a 403 with a body of Invalid Signature, the signature you calculated is not correct... Chrome for whatever reason was combining the two requests into a CORS errors which is not the case, very frustrating.

Turns out, I had a logic issue and was calculating the signature with the incorrect action. You might want to use HTTP toolkit to intercept your browser activity and see what is actually going on with those supposed "CORS" errors.

If that doesn't help, good luck!

from python-storage.

6be709c0 avatar 6be709c0 commented on September 22, 2024

@danjenson, thank you, I can confirm that it is not a cors issue but just an error from Chrome.

image

I had a typo issue. Here is what the function is expecting >
image

From browser >
image

To GCP >
image

Code >
image

from python-storage.

mohsinkhansymc avatar mohsinkhansymc commented on September 22, 2024

@danjenson i dont know if you have resolved this but the response headers in cors need to match your access-control-request-headers so in your case you only need contenttype in there. try using this and test, this should fix your preflight call 🤞
[{ "origin": [ "*" ], "responseHeader": [ "Content-Type" ], "method": [ "PUT", "POST" ], "maxAgeSeconds": 3600 }]

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

@danjenson Can we close this issue?

from python-storage.

danjenson avatar danjenson commented on September 22, 2024

Sorry, we've moved on from this for now.

from python-storage.

HemangChothani avatar HemangChothani commented on September 22, 2024

Closing this issue for now as many users suggested the solution and agreed with it , feel free to reopen if it happen again.

from python-storage.

sebelik avatar sebelik commented on September 22, 2024

I am seeing similar behavior as @hendrikfrentrup.

In my case, the server provides the signed URL directly to the client to start a resumable upload. The client performs an empty POST request to the signed URL to receive a session URL. For this initial request, CORS works fine - the client receives Access-Control-... headers for both the preflight OPTIONS request and the POST request. So far so good.

However, when the client tries to upload the individual file chunks, things break. The resumable upload is a series of PUTs (with an appropriate Content-Range value) to the session URL received in response to the first POST. For these PUT requests, however, the preflight response contains the CORS headers, but the PUT response itself does not causing the browser to throw an error.

All of this happens on the client, so the Origin header is exactly the same for all of these requests. So it seems there's something wrong with the way GCS is handling CORS specifically for PUT requests to these session URLs.

Here's the CORS configuration on my bucket:

[
  {
    "origin": [ "*" ],
    "method": ["DELETE", "GET", "HEAD", "POST", "PUT", "PATCH"],
    "responseHeader": ["Content-Type", "Content-Length", "Content-Range", "Access-Control-Allow-Origin", "X-Requested-With", "X-Goog-Resumable"],
    "maxAgeSeconds": 360
  }
]

from python-storage.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.