This article has participated in the third “topic writing” track of the Denver Creators Training Camp. For details, check out: Digg Project | Creators Training Camp third is ongoing, “write” to make a personal impact.

This article intends to revisit the cross-domain problem. This article will add their own understanding, for very familiar friends, can be skipped.

XMLHTTPRequest

XHR is short for XHR, and its role is that the user interacts with the server. Using HXR to fetch data from the server at a specific URL without refreshing the page. A lot of use in AJAX.

Simply encapsulate an AJAX

Const data = {url: "/", type: "get", async: true, params: {username: "sun", age: 18 }, success: (res) => { console.log(res) }, error: (res) => { console.log(res) } }; function ajax(data) { const key = Object.keys(data.params); let params = []; for (let i = 0; i < key.length; i++) { params[i] = key[i] + "=" + data.params[key[i]]; } // username=sun&age=18 const string = params.join("&"); const url = data.url + "?" + string; const xhr = new XMLHttpRequest(); // Allow cookies to pass xhr.withCredenttials = true xhr.open(data.type, url, data.async); xhr.send(); Xhr.onreadystatechange = function () {if (this.readyState === 4 && this.status === = 200) { data.success(this.response); } else { data.error(this.responseXML); } } } ajax(data);Copy the code

Here is a simple application of AJAX to XHR: Open () opens the connection to the server, and send() waits for onreadyStatechange () to complete before closing it. Onreadystatechange () is called when readyState changes.

ReadyState has five values:

  • 0: The proxy is created, but the open() method is not called
  • 1: The open() method is called
  • 2: The send() method is called
  • 3: The responseText property contains some data during download
  • 4: The download is complete

When using XMLHTTPRequest or img tags, you are constrained by the same origin policy. Next, let’s look at the same origin policy.

The same Origin policy and XMLHTTPRequest

The same origin policy is one of the browser security policies used to restrict the interaction between documents or loaded scripts from one origin and another source.

Homologous vs. dissimilar sources (cross-domain)

Homology means that the protocol, domain name, and port of the requesting party and the requested party are the same.

A domain name is a domain name, not an IP. Different domain names indicate different hosts. Different ports indicate different services to be requested.

If the source is different, we call it cross-domain, and then we’ll show you how to do cross-source access, also known as cross-domain.

Cross-source network access

When using XMLHTTPRequest or img tags, you are constrained by the same origin policy.

These interactions generally fall into three categories:

  • Cross-domain writes are usually allowed. Examples include link links, redirects, and form submission. A select few HTTP requests require adding PreFlight
  • Cross-domain resource embedding is generally allowed.
  • Cross-domain reads are generally not allowed, but can often be cleverly read access with embedded resources.

Here are some examples of resources that might be embedded across sources:

  • <script src="..." ></script>Tag embedding across domain scripts. Syntax error messages can only be captured in the same origin script.
  • <link rel="stylesheet" href="..." >Embedded in the CSS.
  • Display images with the IMG tag.
  • Play media resources through video and Audio.
  • through<object>Embedded plug-ins.
  • Introduce fonts with @font-face.
  • through<iframe>Load any resource.

In addition to the above, what other methods can allow cross-domain access?

CORS

CORS(Cross-source Resource Sharing) is a mechanism based on HTTP headers. The mechanism is to allow the server to identify any origin(domain, protocol and port) other than itself that can access and load the resources, so that the browser can access and load the resources.

CORS requires both browser and server support. The server needs to configure the request header information, and the browser automatically adds some additional header information when an AJAX request (XMLHTTPRequest) crosses the source.

Therefore, the key to CORS communication is the server, which can cross sources as long as it implements the CORS interface.

Browsers classify CORS requests into two categories: simple and complex.

A simple request

Simple requests do not trigger CORS precheck requests. Here’s a simple request:

  • Use one of the following methods:

    • GET
    • HEAD
    • POST
  • The fields set by the user cannot exceed the following:

    • Accept
    • Accept-Language
    • Content-Language
    • Content-type: limited to text/plan, multipart/form-data, Application/X-www-form-urlencoded

This is to be compatible with form forms because historically forms have always been requested across domains. So AJAX design is that as long as the form can be posted, AJAX can be posted.

The browser adds a field Origin in the header of a simple request to indicate which source the request came from.

GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-language: en-us Connection: Keep alive - the user-agent: Mozilla / 5.0...Copy the code

The server determines whether the request can be made based on the Origin field. If the Origin source is not allowed by the server, the server returns a normal HTTP response to the browser. Not a response containing the access-Control-Allow-Origin field.

If the response header does not contain the access-Control-Allow-Origin field, the browser knows it is incorrect and will be caught by the ONError callback of HMLHttpRequest.

If Origin specifies a source within the permissible range, the server adds several messages to the response header:

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
Copy the code

What this information means:

  • Access-Control-Allow-Origin

    • This field must be present to indicate which Origin cross-source requests are allowed, and can be * to indicate that all are allowed.
  • Access-Control-Allow-Credentials

    • Optional field, a Boolean value. True: indicates whether cookies are allowed in the current CORS request. The default is false.
  • Access-Control-Expose-Headers

    • Non-required fields that specify which fields are allowed to be retrieved by the getResponseHeader() method of the HMLHttpRequest object. If not, the following fields can be retrieved by default: Cache-Control, Content-language, Content-Type, Expires, Last-Modified, and Pragma.

The decision to Allow cookies is not just about the server setting the access-Control-allow-credentials field to true. You need to enable the withCredentials attribute in AJAX. Otherwise, the browser won’t send the Cookie.

Note: If cookies need to be sent, the access-Control-Allow-Origin field cannot be set to *, and the document. Cookie in the original web page code cannot read cookies under the server domain name

Non-simple request

Non-simple requests are requests that have special requirements on the server, for example, the request method is PUT or DELETE, or the content-Type field is application/ JSON

CORS that are not simple requests add an HTTP query request, called a ‘preflight’ request, before formal communication.

The browser first asks the server if the domain name of the current web page is on the server’s licensed list, and what HTTP verb and header fields are available. The browser will only issue the XMLHttpRequest request if it is confirmed, otherwise an error will be reported.

Take this request for example:

var url = 'http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();
Copy the code

The request method is PUT, and the x-custom-header is inserted in the Header. When the browser realizes that this is not a simple request, it issues a precheck request and asks the server to confirm whether it can do so.

Precheck request header information:

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
Copy the code

The precheck request uses the OPTIONS method, indicating that the request is for questioning. In addition to the Origin field, the precheck request header information contains two special fields:

  • Access-Control-Request-Method

    • List the HTTP methods used by browser CORS requests, such as PUT above
  • Access-Control-Request-Headers

    • Is a comma-separated string that represents the additional header information field to be sent.

Response to precheck request: When the precheck request is complete, the response is ready.

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
Copy the code

Access-control-allow-origin indicates that the current source can request data, and the server responds to other CORS related fields:

Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
Copy the code
  • Access-Control-Allow-Methods

    • A required field whose value is a comma-separated string that represents the cross-source request method supported by the server. The goal is to avoid multiple precheck requests.
  • Access-Control-Allow-Headers

    • If the browser Request header contains the Access-Control-request-HEADERS field, this field is required for the server. Values are comma-separated strings that represent all header information fields supported by the server, not limited to those requested by the browser in precheck.
  • Access-Control-Allow-Credentials

    • This field has the same meaning as when requested and is related to cookies.
  • Access-Control-Max-Age

    • Optional fields. Indicates the validity period of the precheck request, in seconds. That is, the number of seconds allowed to cache this response, during which no precheck request needs to be sent.

After prechecking the request, the browser’s normal CORS request header:

PUT /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
Copy the code

The server responds:

Access-Control-Allow-Origin: http://api.bob.com
Content-Type: text/html; charset=utf-8
Copy the code

The access-Control-Allow-Origin field is mandatory for each response.

conclusion

This article is mainly explained as follows:

  • XMLHttpRequest is the root of AJAX request encapsulation.
  • The reason some AJAX requests cannot cross domains is because of the same origin policy, which is browser-specific.
  • In addition to partial tags, there are CORS to solve the cross-domain request problem.
  • The principle of CORS, and the details of its work.