current position:Home>Why can't XMLHttpRequest request resources across domains

Why can't XMLHttpRequest request resources across domains

2021-08-26 00:41:41 Mushroom with pepper

This article has participated in the third phase of nuggets creators training camp 「 Topic writing 」 Track , View details : Project digging | The third phase of the creator training camp is under way ,「 Write 」 Personal influence .

This article intends to revisit the issue of cross domain . This article will add its own understanding , For friends who know very well , You can skip .


XHR It's his short name , Its role is to interact with the server . adopt HXR Through a specific... Without refreshing the page URL Get data from the server .AJAX It is widely used in many fields .

Simply encapsulate a AJAX

//  Only consider for the time being get request , Don't consider IE Compatibility 
const data = {
    url: "/",
    type: "get",
    async: true,
    params: {
        username: "sun",
        age: 18
    success: (res) => {
    error: (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 Cookie Pass on 
    xhr.withCredenttials = true, url, data.async);
    //  If the connection to the server is successful, execute this function immediately 
    xhr.onreadystatechange = function () {
        if (this.readyState === 4 && this.status === 200) {
        } else {
 Copy code 

It's on it AJAX Yes XHR Simple application of ,open() Will open the association with the server ,send() Will wait for onreadystatechange() After the function is completely completed, execute close . When readyState When things change onreadystatechange() Function will be called .

readyState There are five values :

  • 0: The agent is created , But it didn't call open() Method
  • 1:open() Method is called
  • 2:send() Method is called
  • 3: In the download ,responseText Property contains some data
  • 4: Download operation completed

In the use of XMLHTTPRequest perhaps img When labeling , Will be constrained by the same origin policy . Next, let's look at the homology strategy .

The same-origin policy And XMLHTTPRequest

Homology policy is one of the browser security policies , Used to limit a source (origin) A new document or loaded script interacts with another source .

Homology And Different sources ( Cross domain )

Homology refers to the agreement between the requesting party and the requested party 、 domain name 、 When the three ports are consistent , We call it homology .

The domain name here is the domain name , No IP. Domain name is different , Indicates that the host is different . Different ports , Indicates that the requested service is different .

If different sources , We call it cross domain , Next, let's introduce how to conduct cross source access , That is often referred to as cross domain .

Cross source network access

In the use of XMLHTTPRequest perhaps img When labeling , Will be constrained by the same origin policy .

These interactions are usually divided into three categories :

  • Cross domain writes are usually allowed . for example link link 、 Redirection and form submission . A specific minority HTTP The request needs to add preflight
  • Cross domain resource embedding is generally allowed .
  • Cross domain read operations are generally not allowed , However, it is usually possible to skillfully read and access through embedded resources .

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

  • <script src="..."></script> Tags are embedded in cross domain scripts . Syntax error messages can only be caught in cognate scripts .
  • <link rel="stylesheet" href="..."> The embedded CSS.
  • adopt img Label display picture .
  • adopt video and audio Play media resources .
  • adopt <object> Embedded plug-ins .
  • adopt @font-face Introduce Fonts .
  • adopt <iframe> Load any resources .

In addition to the above , Is there any other way to allow cross domain access ?


CORS( Cross source resource sharing ) It's based on HTTP The mechanism of head . This mechanism allows the server to identify other than itself origin( Domain , Protocol and port ) You can access and load these resources , So the browser can access and load these resources .

CORS It requires both browser and server support . The server needs to configure the request header information , And the browser found AJAX request (XMLHTTPRequest) Across the source , Some additional header information will be automatically added .

therefore , Realization CORS The key to communication is the server , As long as the server implements it CORS Interface , You can cross source .

The browser will CORS Requests fall into two categories : Simple requests and complex requests .

A simple request

Simple requests do not trigger CORS Pre inspection request . Here is a simple request :

  • Use one of the following methods :

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

    • Accept
    • Accept-Language
    • Content-Language
    • Content-type: Limited to three ,text/plan、multipart/form-data、application/x-www-form-urlencoded

The above is for compatibility with forms form, Because historically, forms can always be requested across domains . therefore AJAX The design is as long as the form can be sent ,AJAX You can send .

Simple request basic process The browser will add a field in the header of the simple request Origin, To explain which source this request comes from .

GET /cors HTTP/1.1
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
 Copy code 

Server according to Origin Field to determine whether the request can be made , If Origin The specified source is not within the allowed range of the server , The server will return a normal message to the browser HTTP Respond . Instead of including Access-Control-Allow-Origin Field response .

The browser found that the information in the response header does not contain Access-Control-Allow-Origin Field , I knew it was wrong , Will be HMLHttpRequest Of onerror Callback function capture .

If Origin The specified source is within the allowable range , The server will add several information in the response header :

Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
 Copy code 

The meaning of this information :

  • Access-Control-Allow-Origin

    • This field must exist , Indicates which... Is allowed origin Cross source request , It can be *, To allow all .
  • Access-Control-Allow-Credentials

    • Non required fields , A Boolean value .true: At present CORS Whether... Is allowed in this request Cookie. The default is false.
  • Access-Control-Expose-Headers

    • Non required fields , Specify that HMLHttpRequest Object's getResponseHeader() Method to get which fields . If there is no default, the following fields can be obtained :Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma.

About whether to allow passing Cookie It's not just the server that will Access-Control-Allow-Credentials Set to true, Need to be in AJAX Open in withCredentials attribute . Otherwise the browser will not send Cookie.

Be careful : If you need to send Cookie, that Access-Control-Allow-Origin The field cannot be set to *, And in the original web page code document.cookie Also unable to read the server under the domain name Cookie

It's not a simple request

Non simple requests are requests that have special requirements for the server , such as : The request method is PUT or DELETE, or Content-Type The type of field is application/json

It's not a simple request CORS, Will be before formal correspondence , Add a HTTP Query request , be called ‘ preview ’ request (preflight).

The browser will first ask the server , Whether the domain name of the current web page is in the server license list , And what can be used HTTP Verb and header fields . The browser will not issue... Until it is confirmed XMLHttpRequest request , Otherwise, it will be wrong .

For example, the following request :

var url = '';
var xhr = new XMLHttpRequest();'PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
 Copy code 

The request method is PUT, The head joined X-Custom-Header Information , The browser found that this is a non simple request , A pre inspection request will be initiated , Ask the server to confirm whether it can request .

Pre check request header information :

OPTIONS /cors HTTP/1.1
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
 Copy code 

The method of pre inspection request is OPTIONS, Indicates that the request is for inquiry . except Origin Field , The information of the pre check request header contains two special fields :

  • Access-Control-Request-Method

    • List browsers CORS What will be used in the request HTTP Method , Like the one above PUT
  • Access-Control-Request-Headers

    • Is a comma separated string , Indicates the header information field for additional transmission .

Response to a pre inspection request : When the pre inspection request is completed , You can respond .

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
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 code 

The fields in the response Access-Control-Allow-Origin Indicates that the current source can request data , Other responses from the server about CORS Relevant fields of :

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 code 
  • Access-Control-Allow-Methods

    • Required fields , Values are comma separated strings , Represents the cross source request method supported by the server . The purpose is to avoid multiple pre inspection requests .
  • Access-Control-Allow-Headers

    • If the browser request header contains Access-Control-Request-Headers Field , This field is necessary for the server . Values are comma separated strings , Represents all header information fields supported by the server , Not limited to the fields requested by the browser in the pre check .
  • Access-Control-Allow-Credentials

    • This field has the same meaning as when requesting , And Cookie of .
  • Access-Control-Max-Age

    • Non required fields . Indicates the validity period of the pre inspection request , The unit is in seconds . namely , How many seconds are allowed to cache this response , There is no need to send a pre inspection request within the validity period .

After the pre check request , The browser works normally CORS Request header :

PUT /cors HTTP/1.1
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
 Copy code 

The response from the server is :

Content-Type: text/html; charset=utf-8
 Copy code 

Field Access-Control-Allow-Origin It must be carried with each response .


This article mainly explains as follows :

  • XMLHttpRequest yes AJAX The root of request encapsulation .
  • AJAX Some requests cannot cross domain because of the same origin policy , This strategy is browser's .
  • Solve the problem of cross domain requests except for some tags , also CORS.
  • CORS Principle , And job details .

copyright notice
author[Mushroom with pepper],Please bring the original link to reprint, thank you.

Random recommended