This article focuses on three cross-domain approaches: JSONP, CORS, and postMessage.
Q: Why do cross-domain problems occur? A: The browser rejects cross-domain requests due to the same origin policy. * Note: Strictly speaking, browsers do not reject all cross-domain requests, but actually reject cross-domain reads. The browser’s same-origin restriction policy works like this:
- Generally, browsers allow cross-origin writes, such as links, redirects;
- Generally, browsers allow cross-origin embedding of resources, such as IMG and Script tags;
- Generally, browsers do not allow cross-origin reads. *
Q: When does cross-domain count? A: Non-same-origin requests are cross-domain. Origin – If two pages have the same protocol, port, and host, then they are the same origin.
Q: Why are there cross-domain requirements? A: Scenario — After the project is servized, the services of different responsibilities are dispersed in different projects. Often, the domain names of these projects are different, but one requirement may correspond to multiple services. In this case, the interfaces of different services need to be invoked, so cross-domain occurs.
How to implement cross-domain
In general, the most common cross-domain methods are the following three: JSONP, CORS, and postMessage.
JSONP
A trick created solely for the purpose of implementing cross-domain requests. [Implementation principle] Although because of the impact of the same origin policy, can not through XMLHttpRequest request data on different domains (cross-origin reads). However, it is possible to introduce JS script files on different domains on the page (cross-origin embedding). Therefore, after the js file is loaded, the callback is triggered, and you can pass in the required data as an argument. [Implementation mode (with front and rear end coordination)]
<script type="text/javascript"> function dosomething(data){// handle the data} </script> <script src="http://example.com/data.php?callback=dosomething"></script>Copy the code
$callback = $_GET['callback'];// Get the name of the callback function
$data = array('a'.'b'.'c');// The data to return
echo $callback.'('.json_encode($data).') ';/ / output
? >Copy the code
【JSONP advantages and disadvantages 】 Advantages: Good compatibility (compatible with lower version IE) Disadvantages: 1.JSONP only supports GET requests; 2. 2.XMLHttpRequest has a better error handling mechanism than JSONP
CORS
CORS is a new official solution recommended by the W3C that enables servers to support XMLHttpRequest cross-domain requests. CORS is easy to implement, simply by adding some HTTP headers that allow the server to declare the sources of access allowed.
It is worth noting that, in general, with CORS, asynchronous requests are divided into simple and non-simple requests. The difference between a non-simple request is that a precheck request is sent first. [Simple request] Use one of the following methods and do not manually set the header field set that is safe for CORS:
- GET
- HEAD
- POST
- POST will be counted as a simple request only if the content-type value of the POST method equals one of the following: text/ plain-multipart/form-data-application /x-www-form-urlencodedCopy the code
Request message:
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.91.b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml; q=0.9, */ *; Q = 0.8 Accept - Language: en - us, en. Q =0.5 accept-encoding: gzip,deflate accept-charset: ISO-8859-1, UTF-8; Q = 0.7 *; Q = 0.7 Connection: keep - the alive Referer: http://foo.example/examples/access-control/simpleXSInvocation.html Origin: http://foo.exampleCopy the code
Line 10 of the request message: Origin: foo.example indicates that the request comes from foo.exmaple. Response message:
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.061.
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[XML Data]Copy the code
Line 4 of the response packet: access-control-allow-origin: * Indicates that the resource can be accessed from any foreign domain.
[Non-simple request]
- One of the following HTTP methods is used:
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
- Header fields other than the set of header fields that are safe for CORS are manually set. The set is:
- Accept
- Accept-Language
- Content-Language
- Content-Type (but note the additional requirements below)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- The value of content-type does not belong to one of the following:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
The pre-check request is sent before the real request, as shown in the figure below:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHERCopy the code
Access-control-request-method: POST in the pre-check Request tells the server that the actual Request will use POST. Access-control-request-headers tells the server that the actual Request will carry two custom Request header fields: x-Pingother and Content-Type. Based on this, the server determines whether the actual request is allowed
Precheck in Response to the request
Access-control-allow-origin: foo.example // Identifies acceptable cross-domain request sources; Access-control-allow-methods: POST, GET, OPTIONS // Identifies the acceptable cross-domain request Methods, such as GET, POST, OPTIONS; Access-control-allow-headers: x-pingother, content-type // Specifies the acceptable cross-domain request header; Access – Control – Max – Age: 86400. // Indicates the validity period (seconds) of the pre-request, during which no further pre-request is required.
XMLHttpRequest requests can send credential requests (HTTP Cookies and authentication information), and usually do not send credential information across domains, but there are cases where you need to break through different logon states, so you need to set a special flag bit of XMLHttpRequest to send credential information. For example, in the following code, you can set the withCredentials of XMLHttpRequest to true, so that the browser can send credentials across domains.
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;Copy the code
The browser passes the response result to the client program only when the access-control-allow-Credentials field in the response header returned by the server exists and is true. In addition, access-control-allow-origin must specify the domain name of the request source, otherwise the response fails.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://foo.com
Access-Control-Allow-Credentials: true
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec- 2008. 01:34:53 GMT
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plainCopy the code
The following figure shows the flow chart of a request with credentials attached:
postMessage
The window.postMessage(Message,targetOrigin) method is a new feature of HTML5. You can use it to send messages to other Window objects, whether they belong to the same source or a different source. Currently, Internet Explorer 8+, FireFox, Chrome, Opera and other browsers already support window.postMessage.
otherWindow.postMessage(message, targetOrigin, [transfer]);Copy the code