search
HomeWeb Front-endJS TutorialHow to use CORS of the Koa2 framework to complete cross-domain ajax requests

This time I will show you how to use the CORS of the Koa2 framework to complete cross-domain ajax requests, and how to use the CORS of the Koa2 framework to complete cross-domain ajax requests. take a look. There are many ways to implement cross-domain ajax requests, one of which is to use CORS, and the key to this method is to configure it on the server side.

This article only explains the most basic configuration that can complete normal cross-domain ajax response (I don’t know how to do in-depth configuration).

CORS divides requests into simple requests and non-simple requests. It can be simply thought that simple requests are get and

post requests

without additional request headers, and if it is a post request , the request format cannot be application/json (because I don’t have a deep understanding of this area. If there is an error, I hope someone can point out the error and suggest modifications). The rest, put and post requests, requests with Content-Type application/json, and requests with custom request headers are non-simple requests. The configuration of a simple request is very simple. If you only need to complete the response to achieve the goal, you only need to configure the Access-Control-Allow-Origin in the response header.

If we want to access the http://127.0.0.1:3001 domain name under the http://localhost:3000 domain name. You can make the following configuration:

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, and you can easily get the correct response from the server.

The experimental code is as follows:

$.ajax({
  type: 'post',
  url: 'http://127.0.0.1:3001/async-post'
 }).done(data => {
  console.log(data);
})

Server-side code:

router.post('/async-post',async ctx => {
 ctx.body = {
 code: "1",
 msg: "succ"
 }
});

Then you can get the correct response information.

If you look at the header information of the request and response at this time, you will find that the request header has an extra origin (there is also a referer for the URL address of the request), and the response header has an extra Access- Control-Allow-Origin.

Now you can send simple requests, but you still need other configurations to send non-simple requests.

When a non-simple request is issued for the first time, two requests will actually be issued. The first one is a preflight request. The

request method

of this request is OPTIONS. This request Whether it passes or not determines whether this type of non-simple request can be successfully responded to. In order to match this OPTIONS type request on the server, you need to make a

middleware

to match it and give a response so that this pre-check can pass.

app.use(async (ctx, next) => {
 if (ctx.method === 'OPTIONS') {
 ctx.body = '';
 }
 await next();
});
This way the OPTIONS request can pass.

If you check the request header of the preflight request, you will find that there are two more request headers.

Access-Control-Request-Method: PUT
Origin: http://localhost:3000

Negotiate with the server through these two header information to see if the server response conditions are met.

It’s easy to understand. Since the request header has two more pieces of information, the response header should naturally have two corresponding pieces of information. The two pieces of information are as follows:

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

The first piece of information and origin The same therefore passes. The second piece of information corresponds to Access-Controll-Request-Method. If the request method is included in the response method allowed by the server, this piece of information will also pass. Both constraints are met, so the request can be successfully initiated.

So far, it is equivalent to only completing the pre-check and not sending the real request yet.

Of course the real request also successfully obtained the response, and the response header is as follows (omitting unimportant parts)

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

The request header is as follows:

Origin: http://localhost:3000

This is very obvious, The response header information is what we set on the server, so that's why.

The client does not need to send the Access-Control-Request-Method request header because it has been pre-checked just now.

The code for this example is as follows:

$.ajax({
   type: 'put',
   url: 'http://127.0.0.1:3001/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();
});

At this point we have completed the basic configuration that can correctly perform cross-domain ajax response, and some can be further configured. s things.

For example, so far, every non-simple request will actually issue two requests, one for preflight and one for real request, which results in a loss of performance. In order not to send a preflight request, you can configure the following response headers.

Access-Control-Max-Age: 86400

这个响应头的意义在于,设置一个相对时间,在该非简单请求在服务器端通过检验的那一刻起,当流逝的时间的毫秒数不足Access-Control-Max-Age时,就不需要再进行预检,可以直接发送一次请求。

当然,简单请求时没有预检的,因此这条代码对简单请求没有意义。

目前代码如下:

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();
});

到现在为止,可以对跨域ajax请求进行响应了,但是该域下的cookie不会被携带在请求头中。如果想要带着cookie到服务器,并且允许服务器对cookie进一步设置,还需要进行进一步的配置。

为了便于后续的检测,我们预先在http://127.0.0.1:3001这个域名下设置两个cookie。注意不要错误把cookie设置成中文(刚才我就设置成了中文,结果报错,半天没找到出错原因)

然后我们要做两步,第一步设置响应头Access-Control-Allow-Credentials为true,然后在客户端设置xhr对象的withCredentials属性为true。

客户端代码如下:

$.ajax({
   type: 'put',
   url: 'http://127.0.0.1:3001/put',
   data: {
    name: '黄天浩',
    age: 20
   },
   xhrFields: {
    withCredentials: true
   }
  }).done(data => {
   console.log(data);
  });

服务端如下:

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-Allow-Credentials', true);
  await next();
});

这时就可以带着cookie到服务器了,并且服务器也可以对cookie进行改动。但是cookie仍是http://127.0.0.1:3001域名下的cookie,无论怎么操作都在该域名下,无法访问其他域名下的cookie。

现在为止CORS的基本功能已经都提到过了。

一开始我不知道怎么给Access-Control-Allow-Origin,后来经人提醒,发现可以写一个白名单数组,然后每次接到请求时判断origin是否在白名单数组中,然后动态的设置Access-Control-Allow-Origin,代码如下:

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-Methods', 'PUT,DELETE,POST,GET');
  ctx.set('Access-Control-Allow-Credentials', true);
  ctx.set('Access-Control-Max-Age', 3600 * 24);
 }
 await next();
});

这样就可以不用*通配符也可匹配多个origin了。

注意:ctx.origin与ctx.request.header.origin不同,ctx.origin是本服务器的域名,ctx.request.header.origin是发送请求的请求头部的origin,二者不要混淆。

最后,我们再稍微调整一下自定义的中间件的结构,防止每次请求都返回Access-Control-Allow-Methods以及Access-Control-Max-Age,这两个响应头其实是没有必要每次都返回的,只是第一次有预检的时候返回就可以了。

调整后顺序如下:

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();
});

这样就减少了多余的响应头。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

在Vue2.0中http请求以及loading的展示

process和child_process使用详解

The above is the detailed content of How to use CORS of the Koa2 framework to complete cross-domain ajax requests. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
如何使用Flask-CORS实现跨域资源共享如何使用Flask-CORS实现跨域资源共享Aug 02, 2023 pm 02:03 PM

如何使用Flask-CORS实现跨域资源共享引言:在网络应用开发中,跨域资源共享(CrossOriginResourceSharing,简称CORS)是一种机制,允许服务器与指定的来源或域名之间共享资源。使用CORS,我们可以灵活地控制不同域之间的数据传输,实现安全、可靠的跨域访问。在本文中,我们将介绍如何使用Flask-CORS扩展库来实现CORS功

如何在PHP-Slim框架中使用CORS跨域请求?如何在PHP-Slim框架中使用CORS跨域请求?Jun 03, 2023 am 08:10 AM

在Web开发中,跨域请求是一个常见的问题。这是因为浏览器对于不同域名之间的请求有严格的限制。例如,网站A的前端代码无法直接向网站B的API发送请求,除非网站B允许跨域请求。为了解决这个问题,出现了CORS(跨域资源共享)技术。本文将介绍如何在PHP-Slim框架中使用CORS跨域请求。一、什么是CORSCORS是一种机制,它通过在相应的HTTP头中添加一些额

如何使用 Golang 构建 RESTful API 并实现 CORS?如何使用 Golang 构建 RESTful API 并实现 CORS?Jun 02, 2024 pm 05:52 PM

创建RESTfulAPI并实现CORS:创建项目并安装依赖项。设置HTTP路由处理请求。使用middlewareCORS中间件启用跨域资源共享(CORS)。将CORS中间件应用于路由器,允许来自任何域的GET和OPTIONS请求。

在Beego框架中使用CORS解决跨域问题在Beego框架中使用CORS解决跨域问题Jun 04, 2023 pm 07:40 PM

随着Web应用程序的发展和互联网的全球化,越来越多的应用程序需要进行跨域请求。对于前端开发人员而言,跨域请求是一个常见的问题,它可能导致应用程序无法正常工作。在这种情况下,解决跨域请求问题的最佳方法之一是使用CORS。在本文中,我们将重点介绍如何在Beego框架中使用CORS解决跨域问题。什么是跨域请求?在Web应用程序中,跨域请求是指从一个域名的网页向另一

springboot解决CORS跨域的方式有哪些springboot解决CORS跨域的方式有哪些May 13, 2023 pm 04:55 PM

一、实现WebMvcConfigurer接口@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{/***添加跨域支持*/@OverridepublicvoidaddCorsMappings(CorsRegistryregistry){//允许跨域访问的路径'/**'表示应用的所有方法registry.addMapping("/**")//允许跨域访问的来源'*

为什么我的Go程序无法正确使用CORS中间件?为什么我的Go程序无法正确使用CORS中间件?Jun 10, 2023 pm 01:54 PM

在当今互联网应用程序中,跨域资源共享(CORS)是一种常用的技术,它允许网站从不同的域访问资源。在开发过程中,我们常常会遇到一些问题,特别是在使用CORS中间件时。本文将探究为什么您的Go程序无法正确使用CORS中间件,并提供针对这些问题的解决方案。确认是否已启用CORS中间件首先,确保已在您的Go程序中启用了CORS中间件。如果没有启用,那么您的程序将无法

PHP通信:如何实现跨域数据传输?PHP通信:如何实现跨域数据传输?Aug 20, 2023 am 11:17 AM

PHP通信:如何实现跨域数据传输?引言:在网页开发中,常常需要实现不同域名之间的数据传输,这就需要跨域通信。本文将介绍使用PHP语言实现跨域数据传输的方法,并附上代码示例。一、什么是跨域通信?跨域通信指的是在网页开发中,不同域名间进行数据传输的过程。通常情况下,由于同源策略的限制,浏览器会阻止页面向不同域的服务器发送请求或接收响应。因此,为了在不同域之间实现

如何在空洞中找回遗失的宝箱如何在空洞中找回遗失的宝箱Jan 22, 2024 pm 05:30 PM

绝区零找回遗失在空洞中的宝箱怎么完成呢?这个副本里的箱子很多,但是因为散落在各处,很多人都找不到,下面我们就和你们一起分享一下如何快速找到箱子通关副本。绝区零找回遗失在空洞中的宝箱怎么完成在绳网中看到委托贴子;具体分析:1、我们可以先去绳网中看到委托贴子【找回遗失在空洞中的宝箱】,然后选择发送信息。2、交流兑换以后就可以去领取这个委托任务了,然后就可以开启这个做法了。3、然后需要我们进入空洞就可以解锁这个任务了呢。4、然后我们就可以接取盗洞客的委托,还可以得到很多数量的齿轮硬币。5、出空洞当中需

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft