跨域请求如何携带cookie?不小心都拿了Offer

跨域请求如何携带cookie?不小心都拿了Offer,第1张

最近在参加面试找工作,陆陆续续的面了两三家。其中面试官问到了一个问题:如何解决跨域问题? 我巴巴拉拉的一顿说,大概了说了四种方法,然后面试官紧接着又问:那跨域请求怎么携带cookie呢?(常规的面试套路,一般都会顺着你的回答往深了问)由于之前的项目都是同源的,不牵涉跨域访问,所以一时没有回答出来,后来研究了下,所以有了这篇文章

阅读本文,你将学到:

思路:

先看下代码结构,相对比较的简单:

A 服务的代码:

index.html 的代码:

B 服务的代码:

首先我们先在 A 服务的 index.html 页面中得到一个 cookie ,运行 A 服务:

然后打开 http://localhost:8000/static/index.html : 没有问题的话,页面长这样:

这个时候 F12 打开控制台: 可以看到发送了一个 login 请求,并且设置了cookie,也可以选择浏览器控制台的 Application 页签,选中 cookie ,可以看到 cookie 的信息:

然后我们点击页面上的 发送同源请求 按钮,可以看到发送了一个user请求,并且已经携带上了cookie:

接下来刺激的画面来了,我们点击 发送跨域请求 按钮,出现了跨域请求的报错:

重点 : 接下来开始解决跨域携带cookie问题:

什么是withCredentials?

XMLHttpRequest.withCredentials 属性是一个Boolean类型,它指示了是否该使用类似cookies,authorization headers(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。在同一个站点下使用withCredentials属性是无效的。

如果在发送来自其他域的XMLHttpRequest请求之前,未设置withCredentials 为true,那么就不能为它自己的域设置cookie值。而通过设置withCredentials 为true获得的第三方cookies,将会依旧享受同源策略,因此不能被通过document.cookie或者从头部相应请求的脚本等访问。

这个时候再去发送一个跨域请求,你会发现依旧报错,但是我们仔细看下报错,意思是需要设置header的 Access-Control-Allow-Origin 属性:

我们修改 B (app2.js)服务的代码:

修改完之后再次发送一个跨域请求,你会发现,又报错了(接近崩溃),但是跟之前报的错不一样了,意思大概就是 Access-Control-Allow-Credentials 这个属性应该设置为 true ,但是显示得到的是个 '' :

再次修改B服务的代码(每次修改后需要重新运行):

再发送一个跨域请求:

可以看到,这个跨域请求已经请求成功并且返回数据了!而且也携带了A服务的cookie,这个时候已经大功告成了。

从技术层面来讲,我们可以设置 <img>标签需要带上cookie等凭据来向后端请求图片资源,后端检测凭据是否合法来决定是否返回相应资源

以 img 标签为例,其它例如 <audio>、<img>、<link>、<script>和 <video>均有一个跨域属性 (crossOrigin property),它允许你配置元素获取数据的 CORS 请求。

设置 crossorigin="use-credentials"表示请求将带上凭据:

Note: The domain must match the domain of the JavaScript origin. Setting cookies to foreign domains will be silently ignored.

https://stackoverflow.com/a/6761443

用于演示携带的 cookie

因为是跨域请求,这时候要浏览器带上cookie就需要设置以下红色框的内容,又因为是 https 请求,所以要设置绿框的内容

web服务器的设置(nginx):

最终可以看到请求中携带了cookie:

情形: egg.js 做后端接口, jQuery做前端请求。

设想:调用user/login接口后,后端设置cookie,然后前端每次请求都会自动带上cookie。

然而现实是后面的请求在控制台中,根本没有cookie而且后端打印后面的接口也是没有cookie的。

后端跨域设置见: https://www.jianshu.com/p/202d760758d2

解决办法:

后端设置cookie:

前端ajax接口(login接口,后续的接口)都加上withCredentials:

xhrFields: {

withCredentials: true

},

crossDomain: true,

ajax设置后,已经有cookie了。

egg.js controller中其他接口中获取浏览器带过来的cookie:

清除cookie直接使用null替换即可:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11498091.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存