A few years ago, website developers hit the south wall with the same-origin ajax policy. When we were amazed at the huge progress of cross-browser support for XMLHttpRequest objects, we soon found that there was no way for us to use JavaScript to request cross-origin access, which we lamented. Everyone builds a proxy (which was the onset of a new host of open redirect problems) on their own website to get rid of this restriction. While developers have avoided this restriction by using server proxies and other techniques, community-based protesters allow ajax to be called locally across domains. Many people have not realized that almost all browsers (Internet Explorer 8 +, Firefox 3.5 +, Safari 4 +, and Chrome) can support Cross-Origin Resource Sharing through the Cross-Origin protocol.
Cross-origin Resource Sharing (CORS)
Cross-Origin Resource Sharing (CORS) is the W3c working draft, which defines how the browser communicates with the server during Cross-Origin Resource access. The basic idea behind CORS is to use a custom HTTP header to allow the browser and server to understand each other and decide whether the request or response is successful.
For a simple request, there is no custom header, either GET or POST, and its subject is text/plain. The request is sent with an additional header named Orgin. The Origin header contains the header of the Request page (protocol, domain name, port), so that the server can easily decide whether it should provide a response.
Origin: http://www.nczonline.net/
If the server determines that the request is passed, it will send an Access-Control-Allow-Origin header to respond to the same source of the request. If it is a public resource, "*" is returned. For example:
Access-Control-Allow-Origin: http://www.nczonline.net/
If the header is lost or the source does not match, the browser rejects the request. If everything goes well, the browser will process the request. Note that both requests and responses do not contain cookie information.
All browsers mentioned earlier support these simple requests. FF3.5 +, Safari 4, and chrome can be used by using XMLHttpRequest objects. When you try to open a resource in different domains, no code is required. This action is automatically triggered. For example:
var xhr = new XMLHttpRequest();xhr.open("get", "http://www.nczonline.net/some_resource/", true);xhr.onload = function(){ //instead of onreadystatechange //do something};xhr.send(null);
The same is true in IE8. In the same way, you need to use XDomainRequest object.
var xdr = new XDomainRequest();xdr.open("get", "http://www.nczonline.net/some_resource/");xdr.onload = function(){ //do something};xdr.send();
In their comments about CORS, the Mozilla team suggested checking the existence of the withCredentials attribute to determine whether the browser supports CORS through XHR. You can combine the existence of XDomainRequest objects to support all browsers:
function createCORSRequest(method, url){ var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr){ xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined"){ xhr = new XDomainRequest(); xdr.open(method, url); } else { xhr = null; } return xhr;}var request = createCORSRequest("get", "http://www.nczonline.net/");if (request){ request.onload = function(){ //do something with request.responseText }; request.send();}
Firefox, Safari, and Chrome's XMLHttpRequest object have similar full interfaces to IE's XDomainRequest object, and these modes run well. Common interface attributes/methods:
- Abort () -- used to terminate a request already in progress.
- Onerror () -- replace onreadystatechange to detect errors.
- Onload () -- replace onreadystatechange to detect success.
- ResponseText -- used to obtain the response text.
- Send () -- used to send a request.
Preflighted request
Apart from GET or POST, a server transparent authentication mechanism called preflighted requests allows CORS to use custom headers and methods, as well as different subject content types. When you try to use one of the advanced options to create a request, a preflighted request is created. This request uses an optional method and sends the following header:
- Origin -- same as a simple request.
- Access-Control-Request-Method -- Method to be used by the Request.
- Access-Control-Request-Headers -- (optional) List of custom Headers in use separated by commas.
The following example assumes a POST request with the header defined as NCZ:
Origin: http://www.nczonline.net/Access-Control-Request-Method: POSTAccess-Control-Request-Headers: NCZ
During the request, the server can decide whether to allow such requests. The server sends the following header in the response to communicate with the browser.
- Access-Control-Allow-Origin -- same as a simple request.
- Access-Control-Allow-Methods -- List of acceptable Methods separated by commas.
- Access-Control-Allow-Headers -- List of acceptable Headers of servers separated by commas.
- The time when the Access-Control-Max-Age -- preflighted request should be cached.
For example:
Access-Control-Allow-Origin: http://www.nczonline.netAccess-Control-Allow-Methods: POST, GETAccess-Control-Allow-Headers: NCZAccess-Control-Max-Age: 1728000
Once a preflighted request is made, the result will be cached according to the time specified in the response. The first time you make such a request, you will initiate an additional HTTP request.
Both Firefox 3.5 +, Safari 4 +, and Chrome support preflighted requests, whereas IE8 does not.
Credentialed request
By default, cross-origin requests do not provide certificates (cookies, HTTP authentication, and client SSL certificates ). You can specify that a request should send a certificate by setting the withCredentials attribute to true. If the server allows the credentialed request, it will respond with the following header:
Access-Control-Allow-Credentials: true
If a credentialed request is sent, this header is not sent as part of the response. The browser will not pass the response to JavaScript (responseText is an empty string, the status is 0, onerror () is called ). Note that the server can also send this HTTP header as part of the preflight response to indicate that the source allows sending credentiale
D request.
IE8 does not support the withCredentials attribute, which is supported by irefox 3.5 +, Safari 4 +, and Chrome.
Conclusion
In modern web browsers, cross-origin AJAX calls are reliably supported. However, most developers are still unaware of these powerful functions. You only need to do some extra work on JavaScript and the server side to ensure that the correct header is sent to use it. The execution of IE8 lags behind in allowing advanced requests and credentialed requests, but it is expected that its support for CORS will continue to improve. If you want to learn more, I strongly recommend that you check the sample page of Arun rangan.pdf.
Reading
- Cross-domain XHR removed from Firefox 3
- Firefox 3.5/Firebug XMLHttpRequest and readystatechange bug
- Mentioned in Microsoft whitepaper
- XMLHttp Requests For Ajax
- Firebug
- Web definitions: DOM, Ajax, and more
Original article address:Http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
Reprinted address:Http://www.denisdeng.com /? P = 1024
Translation Note: There are several parts in the text that are not translated in the original text, just to make them as clear as possible according to Chinese habits. Sorry. Of course, there are also some poor translations in this article. I hope you can make some suggestions for the change. Thank you!