实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。
本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明(深层次的配置我也不会)。
CORS将请求分为简单请求和非简单请求,可以简单的认为,简单请求就是没有加上额外请求头部的get和post请求,并且如果是post请求,请求格式不能是application/json(因为我对这一块理解不深如果错误希望能有人指出错误并提出修改意见)。而其余的,put、post请求,Content-Type为application/json的请求,以及带有自定义的请求头部的请求,就为非简单请求。
简单请求的配置十分简单,如果只是完成响应就达到目的的话,仅需配置响应头部的Access-Control-Allow-Origin即可。
如果我们在http://localhost:3000 域名下想要访问 http://127.0.0.1:3001 域名。可以做如下配置:
app.use(async (ctx, next) => { ctx.set('Access-Control-Allow-Origin', 'http://localhost:3000'); await next();});
然后用ajax发起一个简单请求,例如post请求,就可以轻松的得到服务器正确响应了。
实验代码如下:
$.ajax({ type: 'post', url: 'http://127.0.0.1:3001/async-post' }).done(data => { console.log(data);})
服务器端代码:
router.post('/async-post',async ctx => { ctx.body = { code: "1", msg: "succ" }});
然后就能得到正确的响应信息了。
这时候如果看一下请求和响应的头部信息,会发现请求头部多了个origin(还有一个referer为发出请求的url地址),而响应头部多了个Access-Control-Allow-Origin。
现在可以发送简单请求了,但是要想发送非简单请求还是需要其他的配置。
当第一次发出非简单请求的时候,实际上会发出两个请求,第一次发出的是preflight request,这个请求的请求方法是OPTIONS,这个请求是否通过决定了这一个种类的非简单请求是否能成功得到响应。
为了能在服务器匹配到这个OPTIONS类型的请求,因此需要自己做一个中间件来进行匹配,并给出响应使得这个预检能够通过。
app.use(async (ctx, next) => { if (ctx.method === 'OPTIONS') { ctx.body = ''; } await next();});
这样OPTIONS请求就能够通过了。
如果检查一下preflight request的请求头部,会发现多了两个请求头。
Access-Control-Request-Method: PUTOrigin: http://localhost:3000
要通过这两个头部信息与服务器进行协商,看是否符合服务器应答条件。
很容易理解,既然请求头多了两个信息,响应头自然也应该有两个信息相对应,这两个信息如下:
Access-Control-Allow-Origin: http://localhost:3000Access-Control-Allow-Methods: PUT,DELETE,POST,GET
新闻热点
疑难解答
图片精选