前言
近期项目组做了很多客户端原生转h5化的工作,将原生的业务逻辑在fe前端实现一遍,因此需要后端配合工作最多的就是要处理各个接口、静态资源的跨域问题,接下来对跨域原理及问题进行一个小的总结。
跨域原理
原因
跨域是浏览器在h5页面施加的一个安全限制,不允许浏览器在当前网站执行或者调用其他“非同源”的资源和脚本,源如:“https://www.baidu.com:10080”,是由三元组组成,即:协议、域名、端口号,h5在请求后端资源时,自身发起的协议哪个属性与后端配置的跨域规则不一致都会导致跨域问题。
h5与请求后端源 | 是否同源 |
---|---|
https://www.baidu.com:10080 http://www.baidu.com:10080 | 非同源(协议不同) |
https://www.baidu.com:10080 https://www.baidu.com:8080 | 非同源(端口不同) |
https://www.baidu.com:10080 www.baidu.com:8080 | 非同源(协议不同,默认http协议) |
https://www.baidu.com:10080/index.html https://www.baidu.com:8080/getInfo | 同源 |
前后端跨域流程
跨域问题产生的流程如下图所示:
我们模拟www.baidu.com/index.html的h5页面中的脚本请求接口www.taobao.com/goods/price/1中的数据
在一个http请求发起时,浏览器首先根据同源策略将自身“源”与后端资源做匹配,若不匹配则发送的请求为跨域请求(请求header中携带origin参数,origin即为h5本地资源地址);接着后端接收到有origin参数的header,将自身资源或接口的跨域策略进行返回。后端一般配置跨域策略有两个维度,视为同源的域名(Access-Control-Allow-Origin)、可执行的http方法(Access-Control-Allow-Methods);最后浏览器根据自身发起请求的源域名和http方法判断是否可跨域。
测试跨域
通过上述原理的讲述,我们作为后端开发,如何对后端资源(接口)是否跨域进行测试呢?模拟浏览器在请求header中添加"origin"即可,在请求header中新增 origin:“www.cloudlearn-h5.speiyou.cn”,测试对应接口是否可以支持www.cloudlearn-h5.speiyou.cn来源的h5请求的跨域操作,如果有支持,返回header中会有对应的支持域名及http方法。如下为模拟从源站www.baidu.com发起www.taobao.com/goods/price/1的跨域请求测试,如果返回的header中有对应Access-Control-Allow-Origin、Access-Control-Allow-Methods,则证明后端资源已经处理跨域。
curl -voa 'www.taobao.com/goods/price/1' -H "Origin:www.baidu.com"