What is cross-domain
The cross-domain story begins with the same origin policy.
Origin indicates the protocol, domain name, and port number, while origin indicates that the protocol, domain name, and port number are all the same in the URL. The same origin policy is a security function of the browser. Scripts from different sources cannot read or write each other’s resources without explicit authorization.
Note the meaning of this “cannot read or write resource”, which mainly limits the following three aspects:
- Cookie, LocalStorage, and IndexDB cannot be read
- DOM and JS objects cannot be retrieved
- The Ajax request could not be sent
Any difference in protocol, domain name, or port is regarded as a different domain. This is called cross-domain.
Although the same-origin policy ensures security, there are too many cross-domain scenarios in actual services. If resources could not read or write to each other simply because they crossed domains, many of the Internet features we see today would be left in the same place. The reason for this is that network policies are flexible and there are ways to bypass the same origin policy and communicate.
Cross-domain solutions
JSONP
Since JS calls to cross-domain files are allowed. As long as we manage to put the data into a JS file on the remote server, it can be called and further processed by the client.
Under the guidance of this idea, people excavated JSONP. One of the key points of JSONP is to allow the user to pass a callback argument to the server, which then returns the data wrapped around the JSON data as a function name, allowing the client to customize its own function to handle the returned data automatically.
For example, I call a server-side callback function in HTML
<! DOCTYPEhtml>
<html>
<body>
<script type="text/javascript">
// Callback exists on the server side
function callback(data) {
console.log(data)
}
</script>// Introduce server-side code here<script src="http://www.baidu.com/jsonp.shtml" type="text/javascript" charset="utf-8"></script>
</body>
</html>
Copy the code
Then at www.baidu.com/jsonp.shtml (note that it is a virtual links, for example, you don’t post browser to access, estimated to be 404), the link requests the server code can write so
** * JSONP test * @return
*/
@RequestMapping(value="jsonp",method=RequestMethod.GET)
@ResponseBody
public String Jsonp(){
return "Callback (' I am the target string ');";
}
Copy the code
This code is written in JAVA, you don’t have to understand JAVA, just notice that it returns what
return "Callback (' I am the target string ');";
Copy the code
Return is a call to a callback. So with JSONP, you only have to remember two roles and two things
- Browser script – Definition: Defines callback, in which is the logic to read data
- Call: Outputs the call to the callback, passing the target data as an input parameter to the callback
This will successfully write the cross-domain message that I am the target string to the target file.
CORS
CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”.
It allows browsers to issue XMLHttpRequest requests to servers from different sources. Although it requires both browser and server support, it is currently available on almost all browsers except for earlier versions of Internet Explorer.
CORS communication process, in fact, does not need any code level coordination and change, by the browser automatic implementation.
For developers, CORS communication is no different from same-origin communication, at least in code. As soon as the browser discovers that AJAX requests cross domains, it automatically adds additional headers and requests as necessary, but the user doesn’t notice.
Browser behavior is generic and automated. Therefore, the key to the realization of CORS is whether the server supports it. Let’s look at the process for understanding the browser-server collaboration on CORS
Simply request the corresponding CORS behavior
Browsers divide requests into simple and non-simple requests. CORS handles these two requests differently. Let’s look at simple requests first:
- The request mode can be HEAD, POST, or GET
- The HTTP header does not exceed the following fields: Accept, Accept-language, Content-language, last-event-ID, and Content-Type(limited to three values: Application/X-www-form-urlencoded, multipart/form-data, text/plain)
A simple request meets these two conditions. For simple requests, the browser issues CORS requests directly. Specifically, add an Origin field to the header information
Origin: http://baidu.com
Copy the code
The Origin field indicates the source (protocol + domain name + port) from which the request is sent. Based on this value, the server decides whether to approve the request or not. The results of server processing fall into two categories
- Disagree: If Origin is not a licensed source, the server will return a normal HTTP response. The browser realizes that the response header does not contain the Access-Control-Allow-Origin field, and knows that something is wrong, throwing an error that is caught by XMLHttpRequest’s onError callback.
- Agree: If Origin specifies a domain name within the license, the server will return a response containing this key header field
Access-Control-Allow-Origin: http://baidu.com
Copy the code
This field indicates which domain names are accepted by the server. Its value is either the value of the Origin field at the time of the request, or an * — indicating that a request for any domain is accepted.
CORS behavior corresponding to a complex request
Some requests have special requirements on the server, such as the request method being PUT or DELETE, or the content-Type field being of Type Application/JSON.
CORS requests that are not simple requests are preceded by an HTTP query request, called a “preflight” request.
The purpose of preflight is to verify that the domain name of the current web page is on the server’s approved list, and to specify the HTTP request methods and header fields that can be used. The browser will issue a formal request only if the request returns a success.
The goal is to avoid “futility.” Remember, formal requests usually carry some information, and it can be bulky. It would be a waste of time if we went to the end of the service with such a huge burden on our shoulders only to find that they didn’t accept you at all. So “pre-checking” before sending a formal request is as necessary a confirmation as getting engaged before getting married.
Note: The “precheck” request uses the request method OPTIONS.
CORS versus JSONP
The advantage of CORS is often over JSONP: JSONP supports only GET requests, while CORS supports all types of HTTP requests. But correspondingly, JSONP is also smooth on lower versions of IE, CORS is not as compatible.
PostMessage cross-domain
This API supports cross-window communication by registering Message events that listen for messages and calling postMessage methods that send messages, starting with H5.
In broad terms, a window can get a reference to another window (such as targetWindow = window.opener) and then distribute a MessageEvent message by calling the targetwindow.postMessage () method on the window. The window receiving the message is free to process this event as needed. Arguments passed to window.postMessage(), such as message, are exposed to the window receiving the message through the message event object.
The postMessage method for sending messages
otherWindow.postMessage(message, targetOrigin, [transfer]);
Copy the code
So otherWindow is a reference to the target window; “Message” is a message to be sent. TargetOrigin limits the scope of the message, usually a string or URI, and the asterisk * means no limit.
The message event that receives the message
var onmessage = function(event) {
var data = event.data;
var origin = event.origin;
}
if(typeof window.addEventListener ! ='undefined') {window.addEventListener('message',onmessage,false);
}else if(typeof window.attachEvent ! ='undefined') {window.attachEvent('onmessage', onmessage);
}
Copy the code
Process to demonstrate
Here’s an example to understand this process:
A Processing of message acceptance and distribution on www.baidu.com/b.html
/ / a page
<iframe id="iframe" src="http://www.baidu.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'icon'
};
// Page A sends messages to page B
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.icon.cn');
};
// Page A receives a message from page B
window.addEventListener("message".function( event ) {
console.log('data from b is', event.data)
});
</script>
Copy the code
B page (www.baidu.com/b.html) Processing of message acceptance and distribution
<script>
// Receive data from page A
window.addEventListener('message'.function(e) {
console.log('data from a is', event.data)
var data = JSON.parse(e.data);
if (data) {
data.age = 100;
// Send data to page A
window.parent.postMessage(JSON.stringify(data), 'http://www.baidu.com'); }},false);
</script>
Copy the code
summary
There are many other cross-domain solutions, such as IFrame, cookie cross-domain or reverse proxy cross-domain, and so on. But in principle, you need to master the ideas mentioned in this section first. As always, when answering cross-domain questions, do not think of going sideways. The most appropriate way is to follow the rules.