I am using express-jwt to build a restful api. Now the client is making duplicate ajax calls, for the first one the initiator is angularjs and for the second one the initiator is other. The first one gets 204 as the response code and the second one gets 200 as the response code. I tried to debug to get to the source of this duplicate requests, but I am not able to.
Below is the header details for the one with 204 status code
Below is the header details for the one with 204 status code
Can any one suggest what could be the issue?
The first call is OPTIONS type. That's a pre-flight call which a browser sends if the page and api are not on same domain.
The purpose of this call is to deal with CORS. Backend usually needs to send the allowed request method types (GET, POST etc.). The browser will then send the real call if the desired request type is among those returned.
Here's a sample of the response headers.
You can ignore it for all intents and purposes. It does not contain any normally useful payload or return data.
Take a look at AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE? for more info.
Those two requests are different one is OPTIONS and other is GET.
For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.
You need to handle in the server when the request method OPTIONS , then you need to exit with out processing.
Related
I'm trying to figure out how to prevent the OPTIONS call from firing on every GET call to our API server.
I'm trying this right now:
.config(function(RestangularProvider) {
RestangularProvider.setDefaultHeaders({"X-Requested-With" :"", "Content-Type": "text/plain"});
})
But it's not doing me any good. Everything still thinks it's application/json so it fires off the preflight call. Is there anything I can do?
Check this out:
OPTIONS requests are what we call pre-flight requests in Cross-origin
resource sharing (CORS).
They are necessary when you're making requests across different
origins.
This pre-flight request is made by some browsers as a safety measure
to ensure that the request being done is trusted by the server.
Meaning the server understands that the method, origin and headers
being sent on the request are safe to act upon.
Your server should not ignore but handle these requests whenever
you're attempting to do cross origin requests.
How to disable OPTIONS request?
I have an AngularJS application that talks to various java services. In the application I have a global http header setting in an http interceptor. That means all the service requests from my application will get the header values.
Now the trouble is that all the services CORS settings won't allow this header value. Couple of services does, while others does not. The service calls to the servers that do not support the header fails, since the http interceptor always puts the header values.
Is there a better way to design, in the above said case, so as to avoid the issue stated?
Appreciate any help...
How about adding a response interceptor, looking for a 401 status? If you get a 401, attempt to do the same request again without the headers this time. If this succeeds, 'whitelist' this domain to make all following requests without the headers that you don't want.
Otherwise, if you have a limited number of services that you are making calls to, maybe whitelist them inside of your request interceptor? This would probably be easier, but it's not very elegant.
If I have foreknowledge that CORS calls made with Angular will, indeed, work, can I suppress the OPTIONS calls so that they don't continue needlessly occurring in production?
This OPTIONS request tells the client if a CORS request will be allowed; and, for those requests, which methods (GET, POST, PUT, etc.) can be executed.
According to W3c options call is not required if you are implementing only simple methods: GET/POST/HEAD.
So where you set your Access-Control-Allow-Methods if it is * try changing it to "GET,POST" and based on the standard (if the browser follows), your browser doesn't need to fire the options call.
To avoid the OPTIONS request you need to make sure that your request is a "simple" request.
A simple cross-site request is one that:
Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Does not set custom headers with the HTTP Request (such as X-Modified, etc.)
Check that Angular isn't setting x-requested-with or anything else unexpected.
I'm trying to implement a simple interceptor that allows me to display a message along the lines of "cannot contact the server" in my Angular app. However as the API is on a different host I'm dealing with CORS pre-flight OPTIONS requests.
I've found that if the API is unavailable Chrome dev tools shows a 503 on the OPTIONS request but Angular's $http interceptor catches a 404 response to the subsequent GET request. I believe this is because the OPTIONS response did not contain the required CORS headers so the GET is actually never performed.
Is is possible to intercept the OPTIONS response? If all I see is a 404 I can't distinguish "server down" from "no such resource".
You can't intercept this request by design - the browser is "checking up" on you, making sure YOU should be allowed to make the request.
We've used three solutions to work around this:
If the problem is that you're using a development environment like NodeJS, and your domain names aren't matching (that is, if you normally wouldn't need to deal with this in Production) you can use a proxy. The https://github.com/substack/bouncyBounceJS NodeJS Module is an easy to use option. Then your Web service request domain will match the domain your page is on, and the check won't be triggered. (You can also use tricks like this in Production, although it can be easily abused!)
Also for temporary use, you can use something like Fiddler or Charles to manipulate the request by faking the required headers, or tell your browser not to check them (--disable-web-security in Chrome).
If you have this problem in Production, you either need to legitimately fix it (adjust the Web service handler to add the required headers - there are only two), or find a way to make the request in a way that doesn't trigger the check. For instance, if you control both the source and target domains, you can put a script on the target that makes the requests to itself. Run this in an IFRAME, invisibly. Then you can use things like postMessage() to communicate back and forth. Large services like Facebook use "XHR bridges" like this for the same reason.
I'm trying to make a POST request between two sites.
I've seen the need to change header of request on server side using the access-allow. My problem is that when I send request I can't see this modification in the response header.
If I go on directly on page the headers are change. If I sent request with GET, I can see too that the headers has been changed. Maybe there is server configuration of http which is forbidden across domain POST request?
I'm using a Ngnix server that serves Drupal sites.
As far as I know, the header you should change is the response header of the site that receive the request (or site 2). Thus, it allows the client (or site 1) to perform a CORS request, adding the header "Access-Control-Allow-Origin" and the domain of site 1 (or '*') into the response.