Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS prevents DELETE calls via XHR #150

Open
TilBlechschmidt opened this issue Feb 18, 2017 · 6 comments
Open

CORS prevents DELETE calls via XHR #150

TilBlechschmidt opened this issue Feb 18, 2017 · 6 comments

Comments

@TilBlechschmidt
Copy link

TilBlechschmidt commented Feb 18, 2017

When sending an HTTP request to the /locations or /location endpoint with the DELETE method using JavaScript the browser sends an HTTP OPTIONS request to ask the server whether or not this type of method is allowed for that specific endpoint. Since the FIND server apparently doesn't know how to handle this type of request it simply returns the dashboard page which (obviously) doesn't contain the appropriate header to tell the client's browser that the DELETE request it is going to make is actually valid.

This all is 'again' part of the Cross-Origin resource sharing specification that made up for some problems a few days ago. The solution would be to integrate a server-side check for requests using the OPTIONS method and returning a list of valid request types (for /locations this would be DELETE and GET if I am not mistaken).

To give an example of such a header:

Access-Control-Allow-Origin *
Access-Control-Allow-Methods GET, DELETE
Access-Control-Allow-Headers accept, content-type

For more detail please consider taking a look at this post over at StackOverflow.

Note that the documentation only contains /locations as a valid DELETE request endpoint but the dashboard actually uses /location with different parameters

@schollz
Copy link
Owner

schollz commented Feb 21, 2017

Thanks, I forgot to Allow the DELETE method. Added it here: e63c654.

Let me know if that works.

@TilBlechschmidt
Copy link
Author

TilBlechschmidt commented Feb 21, 2017

img-2017-02-21-134957
img-2017-02-21-135006
It does not work. I assume it's because the Access-Control-Allow-Methods header is only set for the actual delete request but the browser is sending an OPTIONS request beforehand and expects the header to be present. Instead, the server returns the index page (I assume that's because this is the fallback and the OPTIONS request method is not implemented).

So you'd have to filter out OPTIONS requests, then send the appropriate header as a response and then the browser runs another request with the actual DELETE method after it verified that the DELETE method is actually allowed (that's how I understood it).

@schollz
Copy link
Owner

schollz commented Feb 21, 2017

Thanks, I just added OPTIONS as well: 75a126e

@TilBlechschmidt
Copy link
Author

TilBlechschmidt commented Feb 21, 2017

Still doesn't work. I assume that the problem is not that the header you modified doesn't contain the OPTIONS method but instead it's how the FIND HTTP server reacts to an HTTP request with the OPTIONS method since it simply returns the dashboard instead of returning a response with an Access-Control-Allow-Methods header set.

My assumption is (haven't read through the code though since I'm not that much into Go) that you've got a switch statement or if block that filters out the path that the request comes in at and whether or not the method it uses is actually correct for that specific API endpoint. Since the /locations endpoint is of the DELETE type and not of the OPTIONS type that switch/if block just goes through into the default which appears to be the dashboard.

You have to take into consideration that OPTIONS is a totally different request type similar to how POST, DELETE and GET are.

@schollz
Copy link
Owner

schollz commented Feb 22, 2017

How are you testing it?

@TilBlechschmidt
Copy link
Author

TilBlechschmidt commented Feb 22, 2017

I set up the socket by running the following commands in the browser console:

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("DELETE", "http://localhost:18003/location?group=something&location=somethingElse", true);

then initiating the actual request by running the following:

xmlHttp.send();

which then results in

XMLHttpRequest cannot load http://localhost:18003/location?group=something&location=somethingElse. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

You have to remember that the code above triggers a request of the OPTIONS type first and then (if that went successfully, which in this case it didn't) sends the actual DELETE request that we are attempting to initiate with the above code. That's due to the aforementioned CORS specs...

Note though that this URL endpoint is grabbed directly from the dashboard (since it uses that) but it doesn't matter the /locations?group=something&names=somethingElse one is not working either for me. The one I used in the code example is not documented maybe that's something worth fixing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants