解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

这篇文章我们聊一聊CORS跨域 , 它的全称是"跨域资源共享"(Cross-origin resource sharing) 。
在之前的文章中我们已经详细介绍了如何使用JSONP进行接口跨域请求 , 如果不了解的可以参考作者之前的文章《详解前端jquery中的JSONP如何实现跨域请求》 , 相信一定难不倒聪明的你 。
那么CORS跨域方案和jsonp跨域有何不同呢?读完这篇文章你肯定能找到答案!
跨域案例页面地址:http://client.cors.com:8000/greeter.html , 代码如下:

解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图1
服务器接口地址:http://server.cors.com:3000/data , 服务器代码如下:
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图2
很明显 , 当页面在请求服务器接口时会发生跨域现象 , 如下:
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图3
我们去浏览器Network中看一下请求信息 , 
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图4
如图4所示 , 响应为200 , response Headers信息也很正常 , 这说明在跨域的情况下请求依然可以到达服务器 , 并且服务器能够正常响应 , 但是由于浏览器的同源策略并没有把返回的数据给到页面 。
那么如何让页面在跨域的情况下获取到数据呢?我们回看图3 , 似乎在说少了一个Access-Control-Allow-Origin头 , 那么我们在服务器代码中加一下 。
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图5
现在刷新页面 , 服务器返回的数据就能正常打印出来了 。
'Access-Control-Allow-Origin': '*'表示接受任意域名的请求
携带凭证在跨域的情况 , 服务器有时依然需要鉴权 。通常服务器鉴权都是从cookie中获取信息来判断客户端的身份 , 那么跨域的情况下请求还能传递cookie吗?当然能 , 但是cookie会遵守同源策略!
1)服务器设置cookie
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图6

解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图7
如果需要服务器设置cookie , 必须设置Access-Control-Allow-Credentials: true , 否则会出现如下错误 。
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图8
页面中的xhr对象也必须设置属性withCredentials=true 。
此时刷新页面 , 在页面控制台中通过document.cookie查看server=123 , 你会发现server端设置的cookie并不存在 。上面已经说了cookie会遵循同源策略 , 服务器的域名是server.cors.com , 所以服务器设置的cookie应该是在这个域名下 , 并不会在页面的域名(client.cors.com)下 , 那如何验证服务器设置cookie成功呢?
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图9
  • 先打开接口页面 , 这个页面是同源的;
  • 回到请求页面 , 刷新;
  • 再回到接口页面 , 在控制台通过document.cookie就可以拿到服务器设置的cookie 。
2)页面设置cookie
如果主域名相同 , 比如现在的例子 , 主域名都是cors.com , 那么就可以把cookie设置在这个主域名下 。
document.cookie="client=1;domain=cors.com;"这样服务器就能获取到页面设置的cookie 。
如果连主域名都不一样 , 那就不要妄想在页面上设置cookie让服务器获取到 。这种情况下 , 服务器该如何鉴权呢?
第一种方式是让后端把跨域的接口代理成同域的 , 这样我们的后端可以拿到cookie , 在他那把cookie转发给跨域服务 。
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图10
第二种方式是页面发送请求时在header中附加一个token , 用于鉴权 , 
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图
图11
当刷新页面时 , 页面控制台又报错了 。
解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了

文章插图


推荐阅读