jQuery AJAX and CORS
Overview
CORS is a browser technology that allows for controlled access to resources located outside of a specific domain. It broadens and expands the same-origin policy (SOP). However, if a website's CORS policy is not properly established and applied, it opens the door to cross-domain assaults. CORS does not provide protection from cross-origin attacks like cross-site request forgery (CSRF).
About Cross-Origin Resource Sharing (CORS)
CORS is an HTTP-header-based method that allows a server to specify any origins (domain, scheme, or port) other than its own from which a browser should allow resources to be loaded.
CORS additionally makes use of a technique that allows browsers to send a "preflight" request to the server hosting the cross-origin resource to ensure that the server will allow the actual request. The browser transmits headers indicating the HTTP method and headers that will be used in the real request during that preflight.
An example of a cross-origin request: the front-end JavaScript code delivered from https://domain-a.com makes a request to https://domain-b.com/data.json using XMLHttpRequest.
Browsers block cross-origin HTTP queries launched by scripts for security concerns. The same-origin policy is followed by XMLHttpRequest and the Fetch API, for example. This means that a web application using those APIs can only request resources from the origin from which it was loaded unless the answer from other origins includes the appropriate CORS headers.
Same-origin Policy
The same-origin policy is a cross-origin definition that restricts a website's ability to communicate with resources outside of the source domain. The same-origin policy was established many years ago in reaction to potentially dangerous cross-domain interactions, such as one website obtaining confidential data from another. It normally permits a domain to send queries to other domains but not to receive responses from other domains.
Relaxation of the same origin policy
Because the same-origin regulation is so restrictive, many techniques for getting around it have been proposed. Many websites have interactions with subdomains or third-party sites that necessitate complete cross-origin access. Using cross-origin resource sharing, a regulated relaxation of the same-origin policy is possible (CORS).
The cross-origin resource-sharing protocol employs a set of HTTP headers to specify trusted websites and associated features, such as whether or not authorized access is permitted. These are incorporated in a header exchange between a browser and the cross-origin website being attempted.
What Requests Use CORS?
This cross-origin sharing protocol allows cross-origin HTTP requests for:
- Invocations of the XMLHttpRequest or Fetch APIs, as previously explained.
- Web Fonts (for cross-domain font usage in @font-face within CSS) so that servers can deploy TrueType fonts that can only be loaded cross-origin and utilized by authorized websites.
- Textures in WebGL.
- DrawImage is used to draw images/video frames onto a canvas().
- CSS Shapes made from photos.
This overview of Cross-Origin Resource Sharing includes a discussion of the required HTTP headers.
Functional Overview
The Cross-Origin Resource Sharing standard works by introducing new HTTP headers that allow servers to choose which origins are allowed to access information from web browsers.
Furthermore, for HTTP request methods that can have side effects on server data (specifically, HTTP methods other than GET or POST with certain MIME types), the specification requires that browsers "preflight" the request, soliciting supported methods from the server with the HTTP OPTIONS request method, and then sending the actual request upon "approval" from the server.
Clients can also be informed by servers whether "credentials" (such as Cookies and HTTP Authentication) should be transmitted with requests.
CORS failures occur in errors. However, the specifics of the problem are not visible to JavaScript for security reasons. The code only knows that an error happened. The only way to figure out what went wrong is to look at the browser's console for specifics.
The following sections examine scenarios and provide a breakdown of the HTTP headers utilized.
Introduction - CORS in jQuery AJAX
A common issue for developers is when a browser refuses to access a distant resource. This typically occurs when you execute an AJAX cross-domain request utilizing the jQuery Ajax interface, the Fetch API, or basic XMLHttpRequest. As a result, the AJAX request is not executed, and the data is not retrieved.
CORS is a technique that defines a procedure for determining whether a web page should be allowed to access a resource from a different origin.
AJAX Cross Domain Requests and example
Simple Request
Some queries do not result in a CORS preflight. The old CORS spec refers to them as simple requests, whereas the Fetch spec(which now defines CORS) does not.
The motivation is that the HTML 4.0 <form> element (which predates cross-site XMLHttpRequest and retrieve) may send simple queries to any origin, therefore anyone designing a server must already be guarding against cross-site request forgery (CSRF).
According to this premise, the server does not need to opt-in (by replying to a preflight request) to receive any request that appears to be a form submission, because the threat of CSRF is no worse than the threat of form submission. To share the response with the script, the server must still opt-in using Access-Control-Allow-Origin.
A straightforward cross-domain request is one that:
- Custom headers are not sent (such as X-PINGOTHER, etc.).
- Uses just GET, POST, or HEAD request methods.
The following is an example of a simple cross-domain ajax request:
Preflighted Requests
Unlike basic requests, "preflighted" requests begin with an HTTP request using the OPTIONS method to the resource on the other origin to establish whether the real request can be sent. Such cross-origin requests are prioritized because they may have consequences for user data.
Setting custom headers to XHR causes a preflight request to be sent. To put it simply, the preflight request sends an HTTP request via the OPTIONS method to the resource on the remote domain to ensure that the request is safe to transmit. When headers other than Accept and Accept-Language are provided for non-same origin HTTP GET requests, a preflight request is made, according to W3C.
Example:
Request with Credentials
The ability to make "credentialed" queries that are aware of HTTP cookies and HTTP Authentication information is the most intriguing capability given by both XMLHttpRequest or Fetch and CORS.
Browsers will not send credentials in cross-origin XMLHttpRequest or Fetch invocations by default. When the XMLHttpRequest object or the Request function Object(){ [native code] } is invoked, a certain flag must be set.
Browsers will not send credentials by default for non-same origin requests (such as HTTP Cookies, HTTP Authentication, and client-side SSL certificates). When the XMLHttpRequest object is invoked, a certain attribute must be set.
Example:
The Response
Let's look at how the server response should appear:
Conclusion
- In this article, we have gone through the basics of cross-origin resource sharing, AJAX cross-domain requests, and responses with examples.
- To understand more about these topics, check out the example code snippets and play with them.