I am sending an AJAX request using POST over X-Domain for a widget we are producing for our website. The problem we are facing is that this is getting blocked.
My question is - for "modern browsers" [Chrome, Safari, FF, IE8] - it is my understanding that setting "Access-Control" headers
Access-Control-Allow-Origin: http://www.test.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Will allow these "POST" requests to work ? But for IE7 we need to implement some "custom" JSONP solution?
Am I correct in this ? Anyone ?
This works but not using the standard XmlHttpRequest object. For example in IE8 you should use the XDomainRequest object to send the request. For these scenarios, JSONP is actually easier to use and works cross-browser as implemented in jQuery.
Related
I have an application that require credentials. For the preflight requests, I am returning Access-Control-Allow-Credentials to true only in OPTIONS requests. I assumed that this header would not be necessary in subsequent requests but it is failing.
Is this behaviour expected or should I perform modifications?
The MDN website mentions the following but it is not entirely clear to me:
When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple GET requests are not preflighted. So, if a request is made for a resource with credentials, and if this header is not returned with the resource, the response is ignored by the browser and not returned to the web content.
(source)
The fetch standard includes this note for Access-Control-Allow-Credentials header but it's not clear to me either.
For a CORS-preflight request, request’s credentials mode is always "same-origin", i.e., it excludes credentials, but for any subsequent CORS requests it might not be. Support therefore needs to be indicated as part of the HTTP response to the CORS-preflight request as well.
(source)
I am returning Access-Control-Allow-Credentials to true only in OPTIONS requests assuming that in the following calls this header would not be needed.
The OPTIONS request is successful but the browser blocks the subsequent POST request (which does not include Access-Control-Allow-Credentials to true) with the next message:
You want to make a credentialed CORS request (that is, fetch(..., {credentials: "include"})) that requires a preflight (for example, because it is a POST request with Content-Type: application/json).
Without the Access-Control-Allow-Credentials: true header in the preflight response, the browser would not make the credentialed request in the first place.
Since you set that header in the preflight response, the browser makes the credentialed request (so that the effect happens on the server). But then the response lacks a header Access-Control-Allow-Credentials: true, therefore the browser refuses to make the response accessible to Javascript. This is the same behavior as if you made a simple CORS GET request (which does not require a preflight) but the response lacks an Access-Control-Allow-Origin header.
So you really need this header in both responses.
Have a single entry service which is acting like a facade/proxy service for downstream services. The service will need able to detect if the request is a "page request" or "api/xhr" request to perform error handling (302 redirection or 401).
So far have considered:
To use Accept header and detect text/html follow the following reference, can't tell if this is a good indicator to detect a page request
To introduce a custom header for all "api/xhr" request
To enforce all the "api/xhr" requests to follow a "/api" pattern (troublesome as for certain application the xhr is not a restful api)
Any good suggestions are welcome
Ended up using Option 1
Detect page request using Accept header with value "text/html"
As we do not use ajax for partial view
Usually the non-standard HTTP header X-Requested-With is used. Just the presence of the header should be enough. It has at least one advantage over Accept: It cannot be set on a cross-site request, which helps preventing CSRF.
I have a single-page application which is dependent on a javascript bundle to work. For fetching this bundle's CDN (cloudfront) url, I'm making a call to an AWS API Gateway endpoint which returns a HTTP 302 response having the Location header parameter as the CDN url. Now this CDN Url responds with cache-control headers having a sufficiently large max-age value. All the other browsers like Chrome, Firefox seem to honor this and cache the CDN Url response for further requests. But Safari isn't doing so (Version - 12). However, it does cache the response when I'm making the request to the CDN Url directly. Do I need to add some more headers or some additional metadata in the 302 response to make it work for safari?
I tried fiddling with the cache-control parameters like adding 'immutable' but nothing worked. I googled quite a lot about this issue but nothing concrete turned up.
I expected Safari to work with just the max-age parameter present in CDN's response, but it never caches it.
I'm trying to improve the cache capabilities on my sails application.
Sails generate a Etag with its response but when I try to do a GET request with a header 'if-None-Match' containing the Etag from the previous answer I can't get a 304 not Modified response from the server (the response is indeed not Modified and the Etag I receive is the same as the previous one).
I'm using POSTMAN to test the server responses.
Is there a way for a sails server to send such status code on unmodified responses ? I can't find any resource for Etag usage in sails doc.
Thank you.
Sails.js is based on Express.js and the ETags are generated by Express.js. And according to this answer, weak ETags are generated using CRC32 (source), strong ETags are generated using MD5 (source).
I use DHC - REST/HTTP API Client with If-None-Match header, it works perfect (return 304 Not Modified).
And I found that's because POSTMAN send NO-CACHE header to the server for testing purpose
'cache-control': 'no-cache',
You can follow this answer and turn off this feature then everything will be fine.
Want to know where exactly data will be cached in Restful Webservices? Please avoid saying browsers cache Restful webservices data.
REST is based on HTTP.
In HTTP you do not know if you data is cached somewhere. It may be in the browser or in any node in between the client and the server.
However your REST-Server may add the Cache-Control HTTP header to its response, e.g. Cache-Control: No-Cache to mark the response as not to cache.
It is not assured if this will not be ignored by a proxy or whatever.
Your client can also request to not cache data. In jquery you just add cache: no to the AJAX-request and it will do the trick.
If jquery is not available you will have to use the if-modified-since header (http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#if-modified-since).
Probably this post cleared my doubt.
http://www.openlogic.com/wazi/bid/283625/Caching-web-service-results-can-enhance-Apache-application-performance.