Related concepts
The same origin refers to the same protocol, domain name, port, all three are identical to belong to the same origin.
The same- origin policy browser is safe, and at the global level prohibits the page from loading or executing any script from a domain different from its source, and the interaction of scripts from other sources outside the station with the page is strictly limited.
cross-domain due to browser-origin policy, any protocol, domain name, port three between the sending request URL is different from the current page address is a cross-domain
cross-domain resource sharing (crossover Origin Resource sharing,cors) is a great way to solve cross-domain problems, so you can use XHR to load data and resources from different sources.
See which cases belong to cross-domain access:
Solutions
Fortunately, there are several methods besides cors that can be used to load data into an application from an external data source.
- Document.domain+iframe
- Create script dynamically
- Location.hash+iframe
- Window.name
- HTML5 PostMessage
- Flash
- JSONP (cannot be a real Ajax, essentially dynamic script creation)
- Proxy agent (server proxy)
- CORS
- Xdr
JSONP
JSONP is JSON with Padding ... I really don't know what the meaning of this name is.
The first time you use JSONP, you can use the $.ajax function of jquery. But this has caused a very bad impression. It always makes us think that Jsonp and Ajax are related. And in fact, the two of them are completely different mechanisms. The XHR principle is very clear, is completely asynchronous operation. But what is the principle of JSONP?
JSONP principle
JSONP actually has a big relationship with < script> tags. JSONP the biggest advantage is to realize the role of asynchronous cross-domain, then how exactly did he do it?
In fact, JSONP is using the src attribute of script to realize the function of cross-domain.
< Script ; function processjson (JSON) { //do something with the JSON response } </script ; <script src =; </script ;
The above style is a bit out of line with the front flavor. Explain, actually Processjson, actually is equivalent to a callback function just. We'll take a look at the contents of the SCRIPT–SRC. Use Jsoncallback to specify the callback function name and pass in some parameters name = Jimmy&age = 18
This is all that the front-end sends Jsonp. How do we do that? Or, what is the content of the return?
Very simple, based on the function name specified inside the Jsoncallback –processjson. Use Processjson (data) in the returned JS; To execute.
The server side returns the JS content:
processJSON({ message:"I‘ve already received"});
Then, when the browser receives it, it executes directly. Here, let's simulate how the server side performs a JSONP function.
Jsonp in-depth simulations
We can simulate a real JSONP request. The above is the script written directly to die inside the HTML, so that the results may block the loading of the page. So, we need to do this in a different way, using async to add the script method.
This approach is mainly done by dynamically inserting a script tag. The browser does not have a homologous restriction on the resource reference to the script, and the resource is executed immediately after it is loaded into the page (without blocking).
varfunction(url,callbackName){ var script = docuemnt.createELement(‘script‘); script.src = `${url}&callback=${callbackName}`; document.head.appendChild(script);}varfunction(name){ is ${name}`);}sendJSONP(‘http://girls.hustonline.net?name=jimmy‘,‘sayName‘);
The above is a lite version of the JSONP.
In addition, it is recommended to use jquery's Getjson () and Ajax () for requests.
First look at $.getjson ()
$.getJSON("http://girls.hustonline.net?callback=?"function(result){ console.log(result);});
Here, we need to focus on the connotation of callback= in the URL. The way jquery uses auto-generated numbers eliminates the hassle of naming callbacks. In fact, in the end, it will be replaced by a string of characters, such as: json23153123. This will represent the name of your callback function.
However, it is recommended to use AJAX, because you can inadvertently forget the last?
Send Jsonp using $.ajax ()
$.ajax({ url: ‘http://girls.hustonline.net?name=jimmy‘, dataType: ‘jsonp‘, success: function(name){ console.log(name); }});
Jsonp Disadvantages
- The POST request cannot be sent in this way (here)
- It is also not easy to determine whether JSONP requests fail, and most implementations of the framework are based on the time-out.
Proxy Agent
This method first sends the request to the background server, sending the request through the server, and then passing the result of the request to the front end.
<script ; var f = function { alert (data.name); }; var xhr = new XMLHttpRequest (); Xhr.onload = function () { alert (xhr.responsetext); }; Xhr.open ( ' POST ' , ' http://localhost:8888/proxy?http:/ /geocode.arcgis.com/arcgis/rest/services/world/geocodeserver ' , true ); Xhr.send ( "F=json" ); </script ;
varProxyurl ="";if(Req.url.indexOf ('? ') >-1) {Proxyurl = Req.url.substr (Req.url.indexOf ('? ') +1); Console.log (Proxyurl); }if(Req.method = = =' GET ') {request.Get(Proxyurl). pipe (RES); }Else if(Req.method = = =' POST ') {varPost ="';//Defines a post variable for staging the request body informationReq.on (' Data ', function (chunk) { //through the Req Data event listener function, each time the request body is received, it is added to the post variablePost + = chunk; }); Req.on (' End ', function () { //After the end event is triggered, the post is parsed into the true POST request format via Querystring.parse and then returned to the client. Post = Qs.parse (POST); Request ({method:' POST ', Url:proxyurl, Form:post}). pipe (RES); }); }
Note that if you are acting on an HTTPS protocol request, your proxy first needs to trust the certificate (especially a custom certificate) or ignore the certificate check , otherwise your request will not succeed. A vivid example is provided in 12306.
It is also important to note that for the same request browser will usually read the data from the cache, we sometimes do not want to read from the cache, so we will add a Preventcache parameter, this time the request URL becomes: url?preventcache=12345567 ...; This is not a problem in itself, the problem is that when a proxy proxy request is sent using some front-end framework (such as jquery), the request URL is proxy?url and the preventcache:true is set, the framework does not handle this parameter correctly. The result of the outgoing request becomes proxy?url&preventcache=123456 (the positive length should be proxy?url?preventcache=12356); The request sent after the backend intercept is url&preventcache= 123456, there is no such address, so you can not get the correct result.
CORS
This is a way for modern browsers to support cross-domain resource requests.
When you use XMLHttpRequest to send a request, the browser discovers that the request does not conform to the same origin policy, and adds a request header to the request: Origin, a series of processing in the background, If you decide to accept the request, add a response header to the returned result: Access-control-allow-origin; The browser determines whether the response header contains the value of Origin and, if so, the browser processes the response, we can get the response data, if not the browser directly dismissed , we were unable to get the response data.
<script> /*var f = function (data) {alert (data.name); }*/var xhr = new XMLHttpRequest (); Xhr.onload = function(){ alert (xhr.responsetext); }; Xhr.open (' POST ', ' http://localhost:8888/cors ', true); Xhr.setrequestheader ("Content-type", "application/x-www-form-urlencoded"); Xhr.send ("F=json"); </script><script>/* var _script = document.createelement (' script '); _script.type = "Text/javascript"; _SCRIPT.SRC = "Http://localhost:8888/jsonp?callback=f"; Document.head.appendChild (_script); * * </script>
<script> if (req.headers.origin) { res.writeHead(200, { "Content-Type""text/html; charset=UTF-8", "Access-Control-Allow-Origin":‘http://localhost‘/*, ‘Access-Control-Allow-Methods‘‘GET, POST, OPTIONS‘, ‘Access-Control-Allow-Headers‘‘X-Requested-With, Content-Type‘*/ }); res.write(‘cors‘); res.end(); }</script>
If we remove the Access-control-allow-origin, the browser will dismiss the response and we will not get the data.
One thing to note is that the transparent server validation mechanism of Preflighted request enables developers to use custom headers, get or post methods, and different types of topic content. Summary such as:
1, non-GET, POST request
2. The content-type of the POST request is not a regular three: application/x-www-form-urlencoded (Form submitted using the Post method of HTTP), Multipart/form-data (Ibid., But mainly used when the form submits with the file upload, Text/plain (plain text)
3, the payload of the POST request is text/html
4. Set the custom header
The options request header will contain the following headers: Origin, Access-control-request-method, Access-control-request-headers, after sending this request, The server can set the following header to communicate with the browser to determine whether to allow this request.
Access-control-allow-origin, Access-control-allow-method, access-control-allow-headers
Xdr
This is a cross-domain solution provided by IE8, IE9, which only supports get-to-post requests, and is powerless for cross-domain protocols that are different, such as sending HTTPS requests under the HTTP protocol. Just look at Microsoft's own example.
<! DOCTYPE html><html><body> <h2>Xdomainrequest</H2> <input type= "text" id= "tburl" value="http ://www.contoso.com/xdr.txt " style=" width:300px"><br> <input type="text" id= "TbTO" value="10000" ><br> <input type="button" onclick="mytest ()" value ="Get"> <input type="button" onclick="Stopdata ()" value= "Stop"> <input type="button" onclick="ReadData ()" value ="Read"> <br> <div id="Dresponse"></div> <script> varXdr function readdata() { varDRes = document.getElementById (' Dresponse '); Dres.innertext = Xdr.responsetext; Alert"Content-type:"+ Xdr.contenttype); Alert"Length:"+ xdr.responseText.length); } function err() {Alert"XDR onerror"); } function timeo() {Alert"XDR ontimeout"); } function loadd() {Alert"XDR onload"); Alert"Got:"+ Xdr.responsetext); } function progres() {Alert"XDR onprogress"); Alert"Got:"+ Xdr.responsetext); } function stopdata() {Xdr.abort (); } function mytest() { varurl = document.getElementById (' Tburl ');varTimeout = document.getElementById (' TbTO ');if(Window. Xdomainrequest) {XDR =NewXdomainrequest ();if(XDR) {xdr.onerror = err; Xdr.ontimeout = Timeo; xdr.onprogress = Progres; Xdr.onload = Loadd; Xdr.timeout = Tbto.value; Xdr.open ("Get", Tburl.value); Xdr.send (); }Else{Alert ("Failed to create"); } }Else{Alert ("XDR doesn ' t exist"); } }</script></body></html>
The above is the cross-domain request resources I encountered in the actual project, there is a cross-domain need to pay special attention to the HTTPS protocol to send HTTPS requests, in addition to using proxy agent other than the solution, will be the browser directly block off. If any friend knows the solution, please let me know.
Concepts and workarounds for cross-domain requests