There has always been such a question: why did this request appear twice in the console despite the fact that I only wrote it once in some projects? Today, I carefully reviewed the relevant content and made the following notes:

Question:

As shown in the figure below: the request that was written only once in the project was sent twice in the actual netWork. The first time was the request with options without parameters, and the second time was the request with parameters defined by us

1. Because VUE does not provide ajax request function, it is necessary to use vue-Resource, Axios and other plug-ins to implement Ajax request

2. Axios is essentially an Ajax wrapper around javascript, so when sending a request using Axios, it will beThe same-origin policylimit

What is the same origin policy:

The same origin policy was introduced for browsers by Netscape in 1995. Currently, all browsers implement this policy.

Originally, it means that the Cookie set by page A cannot be opened by page B unless the two pages are of the same origin. “Homologous” means “three identical”.

That is, same protocol, same domain name, same port

Such as:www.example.com/dir/page.ht…

The protocol is http://, the domain name is www.example.com, and the port is 80 (default port can be omitted).

Currently, there are three behaviors that are restricted if they are not homologous :(as shown below 🙂

(1) Cannot read the Cookie, LocalStorage and IndexedDB of non-same-origin web pages.

(2) The DOM of non-homologous web pages cannot be contacted.

(3) Cannot send AJAX requests to non-same-origin addresses (yes, but the browser will reject the response)

In addition, it is possible to get window objects for other Windows through JavaScript scripts. There are currently nine properties and four methods of the Window object that allow a window to touch other pages if they are not homologous pages. (check list)

The purpose of the same origin policy is to ensure the security of user information and prevent malicious websites from stealing data.

So, when we make HTTP requests, the same origin policy can cause cross-domain problems, so let’s talk about cross-domain:

What are the cross-domain scenarios:

About the picture above, here’s an explanation for what I don’t understand:

For example, there are two pages that are accessed using the domain name (http://www.domain.com), and the IP address addressed by the domain name (DNS server) is 192.168.4.12. The other page is directly accessed using this IP address (http://192.168.4.12), and the two pages still cannot communicateCopy the code

Many friends may also have a little knowledge of domain names, like me, I found a relatively clear picture, as follows:

.com Top-level domain (level-1 domain)

Zzvips.com Level-1 domain name

www. zzvips. com secondary domain name

And bingo: Well, the easiest way to remember is to have a few points

Cross-domain solutions:

The same origin policy states that AJAX requests can only be sent to the same url or an error will be reported.

In addition to setting up a server proxy (where the browser requests the same source server, which in turn requests external services), there are three ways to circumvent this limitation.

JSONP

WebSocket

CORS

Json:

JSONP is a common method for cross-source communication between servers and clients. The biggest feature is simple and applicable, all old browsers support, the server changes very small. The basic idea is that the web page requests JSON data from the server by adding a <script> element (the attribute of the script/link/img tag is not subject to the same origin policy), which is not subject to the same origin policy. When the server receives the request, it returns the data in a callback function with a given name.Copy the code

WebSocket

WebSocket is a communication protocol that uses WS :// (non-encrypted) and WSS :// (encrypted) as protocol prefixes. This protocol does not implement the same source policy, as long as the server support, it can be used for cross-source communication.Copy the code

CORS

CORS stands for Cross-Origin Resource Sharing. It is a W3C standard and is a fundamental solution to cross-source AJAX requests. It allows browsers to make XMLHttpRequest requests to cross-source servers, overcoming the limitation that AJAX can only be used from one source. Whereas JSONP can only make GET requests, CORS allows any type of request.Copy the code

CORS requires both browser and server support. Currently, all browsers support this function (IE cannot be lower than IE10).

The entire CORS communication process is completed automatically by the browser without user participation. For developers, CORS communication is no different from the same source AJAX communication; the code is exactly the same. Once the browser realizes that the AJAX request is cross-source, it automatically adds some additional header information and sometimes an additional request, but the user doesn’t notice.

Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, it can communicate across sources.

If you see here, you should know why a request will be initiated twice. Is it because the cORS cross-domain resource sharing is enabled at the back end

CORS Two kinds of requests

Browsers divide CORS requests into two categories: simple requests and not-so-simple requests.

A simple request

A request may be considered a “simple request” if all of the following conditions are met:

1. Use one of the following methods:

GET

HEAD (similar to GET, but HEAD does not return the body of the message, the response can be cached, generally used to check the effectiveness of resources, check the effectiveness of hyperlinks, check whether the page has been string changed, mostly used for automatic search robot to obtain the page logo information, obtain RSS feed information, or pass security authentication information, etc.)

POST

2. In addition to the header fields that are automatically set by the User Agent (such as Connection, user-agent) and other headers that are defined in the Fetch specification to disable header names, manually set fields are the set of header fields defined by the Fetch specification to be safe for CORS. The set is:

Accept

Accept-Language

Content-Language

Content-type (note the additional limitations)

DPR

Downlink

Save-Data

Viewport-Width

Width

There are no custom headers, and the HTTP header is no more than one of these fields

3. The value of content-type is limited to one of the following:

text/plain

multipart/form-data

application/x-www-form-urlencoded

3. Any XMLHttpRequestUpload object in the request does not register any event listeners; The XMLHttpRequestUpload object can be accessed using the XMLHttprequest.upload property.

4. The request did not use a ReadableStream object.

Such as:

The web application of foo.example wants to access the resources of bar.other. The browser requests Origin (Origin: protocol + domain name + port number) to identify the source. The server uses this value to decide whether to allow it to cross domains. If the server allows cross-domain, you need to carry the following information in the corresponding header:

1. Access - Control - Allow - Origin: HTTP: // Foo. Example (or *) 2. access-control-allow-credentials :true 3. content-type :text/ HTML; charset=utf-8Copy the code

Access-control-allow-origin: Which domain name is allowed to cross domains. It is a specific domain name or * (* represents any domain name).

Access-control-allow-credentials: Specifies whether to Allow cookies. By default, CORS does not carry cookies unless this value is true

To manipulate a cookie, there are three conditions:

  1. The server response header should carry access-control-allow-credentials and the value should be true

  2. When the browser initiates an Ajax request, you need to specify withCredentials: true in the header of the request

  3. Access-control-allow-origin in the response header must not be * and must be the specified address

WithCredentials:

Is a Boolean that indicates whether a certificate such as cookies,authorization headers, or TLS client certificate should be used to create a cross-site access-control request. Using the withCredentials attribute under the same site is invalid.

This indicator is also used as an indication that the cookies have been ignored in the response. The default value is false

If withCredentials is not set to true before sending an XMLHttpRequest request from another domain, then it cannot set a cookie value for its own domain. When you set withCredentials to true, the third-party cookies will still enjoy the same origin policy, so they cannot be accessed through document.cookie or the script corresponding to the request header.

Example:

var xhr = new XMLHttpRequest();

xhr.open('GET'.'http://example.com/'.true);

xhr.withCredentials = true;

xhr.send(null);
Copy the code

Non-simple request

If the above conditions do not match, it is a complex request. If it is a complex request, a pre-request with the request mode of options will be initiated, as shown below:

The browser uses the Origin field to ask the server whether the domain name of the current web page is in the server’s license list, as well as what Http verbs and header fields are available

The browser will issue a formal XMLHttpRequest request with related parameters only if the precheck request passes, otherwise it will report an error

A sample precheck request:

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

In addition to Origin, there are two more headers than in a simple request:

Access-control-request-headers: Specifies the additional Request Headers that will be used

Access-control-request-method: Indicates the Request Method, such as PUT

Precheck request response header: (after receiving the precheck request, the server will issue a response if cross-domain is allowed) :

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2021 01:15:39 GMT
Server: Apache/2.061.(Unix)
Access-Control-Allow-Origin: http://liudan.handou.com
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers:X-Custom-Header
Access-Control-Max-Age: 172800
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

In addition to access-control-allow-Origin and access-control-allow-Credentials, there are three additional return values in the response header: access-control-allow-Origin

Access-control-allow-methods: Allows Access

Access-control-allow-headers: Indicates the allowed request Headers

Access-control-max-age: Efficient market for this license, unit: S, so ajax before expiration does not need to be prechecked again

If the browser receives the above response, it is considered cross-domain and is treated as if it were a simple request. The following is a detailed diagram of a complex request: