如何配置ajax请求跨域携带cookie,cors支持ajax请求携带cookie

2019-07-19 15:14:46 浏览数 (1)

有些同学看到这个文章标题有点晕,这是个什么情况呢?

首先咱们来看一下前后端数据交互的一些规则:

1、同域名下发送ajax请求,请求中默认会携带cookie

2、ajax在发送跨域请求时,默认情况下是不会携带cookie的

3、ajax在发送跨域请求时如果想携带cookie,必须将请求对象的withcredentials属性设置为true。

4、此时服务端的响应头Access-Control-Allow-Origin不能为*(星号)了,必须是白名单样式,也就是必须设置允许哪些url才能访问,如:

Access-Control-Allow-Origin: http://api.bob.com

5、除了对响应头Access-Control-Allow-Origin的设置,还必须设置另外一个响应头:Access-Control-Allow-Credentials:true。

接下来咱们来一条条验证:

1、同域名下发送ajax请求,请求中默认会携带cookie,

我们用express构建一个静态资源服务器端口为3000,然后新建一个页面,在页面中直接调用jquery的ajax方法,直接调用此方法会向当前url发送一个get请求:

然后我们看network:

此时时携带有cookie的。

2、ajax在发送跨域请求时,默认情况下是不会携带cookie的。

这次我们在用express搭建一个服务器,端口号为5000,然后在3000端口号的服务器上面的网页中发送ajax请求5000服务器的接口,看看请求结果:

network:

仔细观察是没有cookie的。

接着看第三条:

3、ajax在发送跨域请求时如果想携带cookie,必须将请求对象的withcredentials属性设置为true。我们如果使用jquery发送ajax的话需这样设置withcredentials属性:

此时查看network:

此时cookie又回来了,到此为止前端人员的设置就算完成了,虽然现在ajax执行后,最终调用的是错误回调,那是因为后端还不支持cors。

此时我们验证第四条:

4、此时服务端的响应头Access-Control-Allow-Origin不能为*(星号)了,必须是白名单样式,也就是必须设置允许哪些url才能访问,如:

Access-Control-Allow-Origin: http://api.bob.com

首先在服务端开启cors,并且将Access-Control-Allow-Origin的值设置为*。

通过express构建的服务只需要加载cors中间件,并调用这个中间件,不需要设置任何参数默认就会设置Access-Control-Allow-Origin为*。

重启 端口为5000的服务器,查看network请求头信息是这样的:

此时cookie是携带过去的,这一点通过上面的实验已经验证过了。

而响应头信息是这样的:

响应头中设置了Access—Control—Allow—Origin:*,说明已经支持跨域了。

但是ajax调用后执行的还是错误回调,并且console面板打印了一个错误:

大致意思就是:如果前端请求中的withcretentials的属性为true,后端响应头中的Access-Control-Allow-Origin绝对不能是*。所以会报错,此时如果将ajax请求中的withcretentials属性去掉或者设置成false,就不会报错了,但是那样的话,就不会携带cookie了。

那需要后端如何设置才能支持前端发送ajax请求携带cookie呢,Access-Control-Allow-Origin必须设置成这样子:Access-Control-Allow-Origin: http://api.bob.com,而在express搭建的服务器中只需要配置cors中间件的一个参数就可以了。

此时查看network,请求头信息:

完美携带cookie的,

看看响应头:

响应头中Access-Control-Allow-Origin的值设置成了白名单,但是等等,此时为什么ajax调用后,还是执行错误毁掉呢?

继续看第五条:

5、除了对响应头Access-Control-Allow-Origin的设置还必须设置另外一个响应头:Access-Control-Allow-Credentials:true。

在cors中间件中配置一个参数就可以了:

此时查看network的响应头信息:

查看响应头多了一个Access-Control-Allow-Credentials:true,此时ajax的回调终于是成功回调了。

总结一下,如果公司项目采用前后端分离,后端接口形式以cors支持跨域,而此时前端发送ajax请求需要携带cookie,前端请求必须设置XMLhttprequest实例的withCredenetials属性为true,服务端必须设置Access-Control-Allow-Origin为白名单样式,并且需要在响应头中设置:Access-Control-Allow-Credentials为ture。

cors除了cookie的限制,请求头也做了限制,客户端如果想发送自定义请求头,服务端必须设置Access-Control-Allow-Headers为*,或者白名单的样式,这里使用express中间件的同学注意,cors中间件默认Access-Control-Allow-Headers为*,也就是说直接使用cors中间件可以允许客户端传递任何自定义请求头。

如果想通过cors中间件设置Access-Control-Allow-Headers白名单,如图:

如果设置白名单的话,这个响应头在浏览器中是不会出现的,想想也是,设置了白名单就是为了不让信息泄密啊。

以上是前端发送请求设置自定义请求头,需要服务端配合,设置一个Access-Control-Allow-Header的响应头就可以了。

cors对前端获取响应头的行为也做了限制,默认情况下,前端是获取不到响应头的,这里需要设置一个响应头:Access-Control-Expose-Headers,这个响应头最好不要设置成通配符样式,而要设置成白名单,在cors中间件中这样设置:

这样的话前端就可以通过xmlhttprequset请求对象的实例的getAllResponseHeaders方法得到这个响应头了。

本篇文章耗时三到四个小时,文末我会将代码地址贴出来,供大家参考。

以上便是今天关于ajax、cookie、cors的内容了,有什么问题欢迎留言。

相关资料 axios的cookie跨域以及相关配置https://segmentfault.com/a/1190000011811117 跨域资源共享 CORS 详解 http://www.ruanyifeng.com/blog/2016/04/cors.html cors中间件的使用方法 https://www.npmjs.com/package/cors express如何设置req的header https://segmentfault.com/q/1010000005957500 允许跨域资源共享(CORS)携带 Cookie https://www.jianshu.com/p/6b9a7892fdc7 演示代码地址: https://github.com/clm1100/corsAndProxy

0 人点赞