Talking about the KOA2 framework with Cors to complete the cross-domain AJAX request

There are many ways to implement cross-domain AJAX requests, one of which is the use of CORS, and this method is configured on the server side.

This article only describes the most basic configuration capable of completing normal cross-domain AJAX (I don’t have a deep configuration.

CORS divides the request into simple requests and non-simple requests, can be simply considered that simple requests do not add the GET and POST requests that additionally request the header, and if it is a POST request, the request format cannot be APPLICATION / json (because I don’t understand this problem. If you want someone to point out the error and make a modification). The rest, PUT, POST request, content-type are requests for Application / JSON, as well as requests with custom request headers, are non-simple requests.

Simple request configuration is very simple, if it is only to complete the response, just configure the Access-Control-Allow-Origin that responds to the header.

If we want to access domain names at http:// localhost: 3000 domain. It can be configured as follows:

App.use (async (ctx, next) => {CTX.Set (‘Access-Control-Allow-Origin “,’ http: // localhost: 3000 ‘); AWAIT next ();};
  Then use AJAX to initiate a simple request, such as a POST request, can easily get the server correctly Respond.  
The experimental code is as follows:
$. Ajax ({type: ‘post’, URL: ‘ 3001 / Async-post ‘}). DONE (DATA => {Console.log (data);})

Server-end code: (‘/ async-post’, async ctx => {ctx.body = {code: “1”, msg: “SUCC”}});
Then you can get the correct response information.

At this time, if you look at the header information of the request and response, you will find that the header has more origin (there is a REFERER for the URL address of the request), and the head is more Access-Control-Allow-Origin.
You can now send a simple request, but you want to send a non-simple request or other configurations.
  When a non-simple request is issued for the first time, two requests are actually issued. The first time the preflight request, the request method is Options, whether the request is determined by this one The type of non-simple request can be successfully obtained.  
In order to match the server to this Options type, you need to make a middleware to match and give a response to make this pre-inspection.

App.use (async (ctx, next) => {if (ctx.method === ‘Options’) {ctx.body =’;} await NEXT ();});

This Options request can pass.

If you check the request header of Preflight Request,There will be two request heads.

Access-Control-Request-method: Putorigin: http: // localhost: 3000

To pass this Two head information is negotiated with the server to see if it is in line with the server response condition.
  It is easy to understand that since the request is more than two information, the response head should naturally have two information, both of which are as follows:  

Access-Control-Allow-Origin: http: // localhost: 3000access-Control-Allow-Methods: PUT, DELETE, POST, GET

One information is the same as that of Origin. The second information corresponds to the Access-Control-Request-method, and if the request is included in the response mode allowed by the server, this also passes. The two constraints are met, so the request can be successfully initiated.
 At this time, it is equivalent to completing the premise, and has not sent a real request.   
The real request is of course successful, and the response head is as follows (omitted inhabit)

Access-control-allow- Origin: http: // localhost: 3000access-Control-Allow-Methods: Put, Delete, Post, Get

The request head is as follows:
   Origin: http: // localhost: 3000 
This is obvious, the response header information is we set in the server, so this is the case.

The client does not need to send Access-Control-Request-Method request heads because it has been prepared.
The code of this example is as follows:

$. Ajax ({type: ‘put’, url: ‘ / put ‘}). DONE (DATA => {Console.log (data);});
 Server code:   
App.use (Async (CTX, Next) => {CTX.Set (‘Access-Control-Allow-Origin “,’ http: // localhost: 3000 ‘); CTX.Set (‘ Access- Control-allow-methods’, ‘put, delete, post, get’); await next ();};

To this, we have completed the correct cross-domain The basic configuration of the AJAX response, and some things that can be further configured.
For example, until now, each non-simple request will actually issue two requests, once a pre-inspection, a real request, which compares the loss performance. In order to not send a pre-inspection request, you can configure the next response.
  Access-Control-Max-Age: 86400  
The meaning of this response head is to set a relative time ,At the moment at the server side, when the server side is checked, when the number of milliseconds of the passed time is less than Access-Control-Max-Age, it is not necessary to perform a pre-inspection, and a request can be sent directly.
Of course, there is no pre-inspection when simply requested, so this code is meaningless to simple request.

Current code is as follows:

app.use (async (ctx, next) => {CTX.Set (‘access-control- Allow-Origin ‘,’ http:// localhost: 3000 ‘); CTX.Set (‘ Access-Control-Allow-Methods ‘,’ Put, Delete, POST, GET ‘); CTX.Set (‘ Access-Control- MAX-AGE ‘, 3600 * 24); AWAIT next ();};

To now, the cross-domain AJAX request can be responded, but the domain The cookie below will not be carried in the request head. Further configuration is required if you want to take a cookie to the server and allow the server to further set up the cookie.
In order to facilitate subsequent detection, we set two cookies at in this domain name. Be careful not to set the cookie into Chinese (I just set it into Chinese, the result is wrong, I haven’t found an error reason for the error)
 Then we have to do two steps, the first step Set Response Head Access-Control-Allow -Credentials is True and then set the XHR object with the XHR object to TRUE on the client.   The client code is as follows: 
$. Ajax ({Type:’Put’, URL: ‘’, Data: {Name: ‘Huang Tianhao’, AGE: 20}: true}}). DONE (DATA => { Console.log (data);};

The server is as follows:
   app.use (async CTX, Next) => {ctx.set ('access-constol-allow-Origin', 'http: // localhost: 3000'); CTX.Set ('Access-Control-Allow-Methods',' Put, Delete , POST, GET '); CTX.Set (' Access-Control-Allow-Credentials', True); AWAIT next ();}; 

You can take a cookie to the server, and the server can also change the cookie. But cookie is still cookies under the domain name, no matter how it is operating under this domain name, you cannot access the cookie under other domain names.

The basic functions of CORS are now mentioned.
 I didn't know how to give Access-Control-allow-Origin, and then I went to write a white list array, and then judge whether origin is in white list each time you receive a request. In arrays, then dynamically set Access-Control-Allow-ORIGIN, the code is as follows:   
App.use (async (ctx, next) => {if (ctx.request.header.origin! == CTX.ORIGIN & & WHITELST.INCLUDES (CTX.Request .Header.origin) {CTX.Set (‘Access-Control-Allow-Origin’, CTX.Request.Header.origin); CTX.Set (‘Access-Control-Allow-Methods’,’ Put, Delete, POST Get ‘); CTX.Set (‘ Access-Control-Allow-Credentials’, True); CTX.SET (‘Access-Control-Max-Age’, 3600 * 24);} AWAIT next ();});

This can also match multiple ORIGINs without * wildcards.

Note: Ctx.origin is different from ctx.request.Header.origin, CTX.origin is the domain name of this server, ctx.Request.Header.origin is the Origin that sends a request header, Both don’t confuse.

Finally, we will slightly adjust the structure of the custom middleware, prevent each request from returning Access-Control-Allow-Methods and Access-Control-Max-Age, which is actually There is no need to return every time, it is just the first time with the pre-inspection.

After the adjustment sequence is as follows:
app.use (async (ctx, neXT) => {if (ctx.Request.Header.origin! == ctx.origin && whitelist.includes (ctx.request.Header.ORIGIN) {ctx.set (‘access-control-allow-Origin “, CTX .request.Header.origin); CTX.SET (‘access-control-allow-credentials’, true);} AWAIT next ();}; app.use (async (ctx, next) => {if (CTX .method === ‘Options’) {CTX.Set (‘Access-Control-Allow-Methods’, ‘Put, Delete, POST, GET’); CTX.SET (‘Access-Control-Max-Age’, 3600 * 24); ctx.body = ‘;} AWAIT next ();};

This reduces excess response head.

The above is all the content of this article, I hope to help everyone, I hope everyone will support Tumi Cloud.

© Copyright Notice
Just support it if you like
comment Grab the couch

Please log in to comment