Contrast XHR cross-domain resource sharing (CORS) and as well as JSONP of: AJAX study notes 2

1 Introduction:

First of all thank the authors refer to the article, your lessons learned to those of us new to offer too many resources.
This paper addresses the problem of CORS AJAX, I combed logically: First, the system summarizes the origin --- CORS-origin policy issues; Secondly, the cross-domain JSONP this way can only support GET requests and CORS for comparison; and finally, the solution described XHR CORS and IE in the XDR solution, provides tools for cross-browser function on the basis of the HTTP request object creation.


Sources --- 2 cross-domain origin policy issues

In the client-side programming language, such as javascript and ActionScript, same origin policy is a very important security concept, its purpose is to ensure the security of user information to prevent malicious sites to steal data.
Imagine this situation: A web site is a bank, after the user logs in, went to visit other sites. If other sites A Web site can read the Cookie, what will happen?

Obviously, if Cookie contains privacy (such as total deposits), this information will leak. Even more frightening is that, Cookie often used to save the user's login status, if the user does not log out, other sites can impersonate the user, do whatever they want. Because the browser also provides that the form is submitted unrestricted homologous policy. Thus, the "same-origin policy" is required, otherwise Cookie can be shared, the Internet, have no security to speak of.

So what is the same domain (homologous), what is different domains (different source) it? When the two domains have the same protocol (such as http), the same port (eg 80), the same host (such as www.example.org), then we can believe that they are the same domain. For example, HTTP: //www.example.org/index .... (the default port number 80 can be omitted) and http: //www.example.org/sub/in ... the same domain, and http: // www.example.org, https://www.example.org, http://www.example.org:8080, any two of http://sub.example.org would constitute a cross-domain.
Note: Only the protocol, the domain name, the port number is exactly the same domain, otherwise, even if the corresponding IP and domain name are different domains, as follows chart: (forget where this image attracted, and thank the author)
image description

Currently, if a non-homologous, a total of three acts is limited.

(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。

As a front-end developers, many times we have to do is break this limitation.

Added: same-origin policy should also do processing for some special cases, such as restrictions on access to the script file under the agreement. Local HTML file in a browser is opened through file protocol, if the script through file protocol access to any other file on your hard disk, there will be a security risk, the current IE8 there is such a risk.

3 a cross-domain embodiment JSONP [Reference 1]

JSONP is JSON with Padding shorthand, is a common way to communicate across the source server and client applications JSON implementation. The biggest feature is simple to apply, all supported by older browsers, servers reform is very small.

The basic idea is that web page by adding a <script> element, JSON data request to the server, this approach is not same-origin policy restrictions; the server receives the request, the name of the data in a specified callback function pass back .
JSOP consists of two parts: the callback function and data, the callback function is a function in response to the arrival should be called, usually by adding a query string; data is incoming JSON data callback function, to be exact, is a JSON object, direct interview.

Example:

//访问跨域src并将数据填入到script标签中的函数
    function addScriptTag(src) {
      var script = document.createElement('script');
      script.setAttribute("type","text/javascript");
      script.src = src;
      document.body.appendChild(script);
    }
//网页动态插入<script>元素,由它向跨源网址src发出请求,src中包含回调函数
    window.onload = function () {
      addScriptTag('http://example.com/ip?callback=foo');
    }
//回调函数的参数默认是返回的数据
    function foo(data) {
      console.log('Your public IP address is: ' + data.ip);
    };

/ The above code is dynamically added <script> element by making a request to the server example.com. Note that the query string of the request has a callback parameter, used to specify the name of the callback function, it is necessary for JSONP. /

The drawback of JSONP
can only be achieved GET, not POST; the code loaded from other domains may be unsafe; JSONP difficult to determine whether the request fails (XHR have error events), it is common practice to use a timer to specify the allowed response time, beyond the time thought failed to respond. CORS JSONP with the same purpose, but more powerful than JSONP, it supports all types of HTTP requests. JSONP advantage is to support older browsers, and can request data from the CORS site does not support.

4 AJAX across domains [Reference 2]

Reference [2] describes a complex HTTP request contained herein simply GET and POST requests.
CORS, namely-Origin Resource Sharing Cross ( https://www.w3.org/TR/cors/ ), cross-domain resource sharing, must be defined in the cross-domain access to a resource, how the browser and server interaction. The basic idea is to use a custom HTTP headers allow the browser and server communicate to determine success and failure responses. Therefore, understanding the cross-domain XHR must understand HTTP header.

4.1 HTTP header

HTTP header into the request header, and response header, when XHR send request, sends the request header:
 the Accept: content type browser can handle.
 Accept-Charset: character set the browser can display.
 Accept-Encoding: compression coding browser can handle.
 Accept-Language: language browser is currently set.
 Connection: the type of connection between the browser and the server.
 Cookie: Cookie any of the current page settings.
 Host: Domain issuing the requested page is located.
 Referer: issuing the request URI page. Note, HTTP header field specifications will spell this wrong, but in order to ensure consistency with the norms, can only be wrong wrong. (The correct spelling of English words should be the referrer.)
 the User-Agent: browser user agent string.
Content-Type: three values limited application / x-www-form- urlencoded, multipart / form-data, text / plain

Using the setRequestHeader () method to set custom request header information. This method takes two arguments: the name and value of the header field of the header field. To successfully send a request header information, and the call must send after calling open () method () method before calling setRequestHeader ().
request.open ( "GET", "https://sf-static.b0.upaiyun.com/v-57fcb48b/user/script/index.min.js", to true);
xhr.setRequestHeader ( "myHeader", " MyValue ");
request.send (null);
in this definition since the header information, a subsequent operation may be performed corresponding to the receiving server.

XHR object calls getResponseHeader () method and pass in the name of the head of the field, you can get the appropriate response headers. Invoking the getAllResponseHeaders () method can achieve a long string comprising all header information, such formatted output we can easily check the names of all the response header field.

Test Example:

  //创建请求对象
  var request = createRequest();
  if (request == null) {
    alert("Unable to create request");
    return;
  }
  request.onreadystatechange = showSchedule;
  //使用DOM0级方法添加event handler,因为不是所有浏览器都支持DOM2;没有event对象,直接使用request对象
  request.open("GET", selectedTab + ".html", true);//返回HTML片段
  request.send(null);
}
function showSchedule() {
  if (request.readyState == 4) {
    if ((request.status >= 200 && request.status <= 300)|| request.status == 304) {
    //返回响应头部
    document.getElementById("content").innerHTML = request.getAllResponseHeaders();
    }else
    {
      document.getElementById("content").innerHTML =request.status;
    }
  }
}

The results showed that all of the output response headers:
Last-Modified: Tue,. 11 On Oct 2016 09:44:48 GMT Content-type: file application / X-JavaScript Cache-Control: max-2592000 Age = Expires: Thu, 10-Nov 09 2016 : 45: 10 GMT

4.2 CORS head covered

IE10 and above, Firefox 3.5+, Safari 4+, Chrome , iOS version of Safari and WebKit Android platform are implemented native support for CORS via XMLHttpRequest object. CORS use absolute positioning can be achieved as long as the URL open () method. It is recommended to use a relative URL in the same domain, use an absolute URL across domains. CORS entire communication process, the browser is done automatically, without user intervention. For developers, there is no difference AJAX communication CORS communicate with homologous, exactly as it was. Once AJAX browser cross-origin request, it will automatically add some additional header information, and sometimes more than a request for additional time, but users do not have feelings. Therefore, communication is the key to achieving CORS server. CORS long as the server implements the interface, you can communicate across the source.

For simple requests (GET and POST), the browser sent directly CORS request. Specifically, it is among the header information, adding a field for describing Origin: this request which source (+ protocol name + port) from. Server based on this value, the decision whether to grant the request.
If Origin specified source, not within the scope of the license, the server returns a normal HTTP response. Browser found this response header information does not include Access-Control-Allow-Origin field (see below), you know wrong, so throw an error, is the XMLHttpRequest onerror callback function to capture. Note that this error code is not recognized by the state, because the HTTP response status code might be 200.
If the domain name specified in the Origin permitted range, the server returns a response, a few extra header field, as follows:

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

The above header information, the three of CORS request related fields, are beginning to Access-Control-. Explained in detail as follows:
(. 1) the Allow-Access-Control-Origin
This field is required. Its value is either the value of the field Origin request either a *, any request for acceptance of the domain name.
(2) Access-Control-Allow -Credentials
This field is optional. Its value is a Boolean value that indicates whether to allow sending Cookie. By default, Cookie CORS not included in the request. Set to true, it means that the server explicit permission, Cookie can be included in the request sent to the server. This value can only be set to true, if the server is not sent by the browser Cookie, you can delete the field.
(3) Access-Control-Expose -Headers
This field is optional. When the request is CORS, getResponseHeader XMLHttpRequest object () method to get only six basic fields: Cache-Control, Content-Language , Content-Type, Expires, Last-Modified, Pragma. If you want to get the other fields must be specified in the Access-Control-Expose-Headers inside. The above example specifies, getResponseHeader ( 'FooBar') can return a value FooBar field.

4.3 test cases

The embodiment in the open () method is changed as shown below, URL points to a JavaScript file in another domain, the test results show that the file is loaded successfully.
// test file on the local host localhost
request.open ( "GET", "https://sf-static.b0.upaiyun.com/v-57fcb48b/user/script/index.min.js"/ selectedTab +" .html " /, to true);

FireBug in FireFox observed using the above-described process in response to the request, the corresponding request header: Origin is http: // localhost

Response headers: access-control-allow-origin: * indicates any source can be accessed.

Cross-domain XHR object can be used to access status and statusText attributes, and supports simultaneous requests, although this is not much use. You can not be used to limit the setRequestHeader () to set custom header; Cookie can not transmit and receive; call the getAllResponseHeaders () method always returns an empty string.

5 Special IE: XDR cross-domain objects

For XHR2, support IE browser IE10 is over. But early in the IE IE8 launched XDomainRequest object cross-domain operations, has been used to IE10 was only replaced out. So IE8, IE9 should be used XDomainRequest (XDR) to achieve. XDR has the following characteristics:
. 1) Cookie not sent with the request, with the response is not returned. (And the same cross-domain XHR)
2) only in the header information setting request Content-Type field.
3) can not access the response headers. (And the same cross-domain XHR)
4) only supports GET and POST requests.

Use XDR object and XHR object is very similar, but also create an instance of a XDomainRequest, call the open () method, and then call the send () method. But open XHR object () different methods, Open the XDR objects () method to receive only two parameters: the type of request and a URL.
All XDR requests are performed asynchronously , you can not use it to create a synchronous requests (XHR different and the same). After requesting the return will trigger the load event (and with XHR), if it fails (including the lack of response in Access-Control-Allow-Origin header) will trigger error events . Also in response to the data stored responseText property of.

var xdr = new XDomainRequest();
xdr.onload = function(){
alert(xdr.responseText);
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);

Before calling request returns abort () method may terminate the request:

xdr.abort(); //终止请求

Like with XHR, XDR objects also support timeout property and ontimeout event handler .
To support the POST request, the XDR object provides contentType attribute used to indicate the format of transmission data. The attribute header information can affect, in open () after, Send () prior to use. This property is affecting only way XDR header information by subject .

6 cross-domain solutions for cross-browser

Even if the browser is not the degree of support for CORS are the same, but all browsers support a simple (non Preflight and without credentials) request, it is necessary to implement a cross-browser solution. Detecting whether to support XHR CORS easiest way is to check whether there is withCredentials property. Combined XDomainRequest detect whether an object exists, you can take care of all the browsers.

function createCORSRequest(method, url){
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr){
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined"){
    vxhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    xhr = null;
  }
  return xhr;
}

Firefox, XDomainRequest similar objects XMLHttpRequest object IE Safari, and Chrome in, provides a common property / method is as follows:
 ABORT (): for requesting stop ongoing.
 onerror: detecting an error onreadystatechange used instead.
 onload: onreadystatechange for detecting successful alternative.
 responseText: to get the response content.
 send (): to send the request.
More members are included in the createCORSRequest function returns an object (), the normally available in all browsers.

var request = createCORSRequest("get", "http://www.somewhere-else.com/page/");
if (request){
    request.onload = function(){
        //对 request.responseText 进行处理
    };
    request.send();
}

Guess you like

Origin www.cnblogs.com/homehtml/p/12595638.html