详解跨域

  • 时间:2020-04-24 20:44 作者:前端陈辉 来源: 阅读:635
  • 扫一扫,手机访问
摘要:跨域问题的场景和处理方案多种多样,只需是做前台开发,总会遇到。而且面试时也是必问的问题。所以自己学习总结记录一下。前置知识:浏览器的同源策略首先需要明确一点:协议、域名、端口都相同才叫同源。同源政策的目的,是为了保证客户信息的安全,防止恶意的网站窃取数据。设想这样一种情况:A网站是一家银行,客户登录

跨域问题的场景和处理方案多种多样,只需是做前台开发,总会遇到。而且面试时也是必问的问题。所以自己学习总结记录一下。

前置知识:浏览器的同源策略

首先需要明确一点:协议、域名、端口都相同才叫同源。
同源政策的目的,是为了保证客户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,客户登录以后,又去浏览其余网站。假如其余网站可以读取A网站的 Cookie,会发生什么?
很显然,假如 Cookie 包含隐私(比方存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存客户的登录状态,假如客户没有退出登录,其余网站即可以冒充客户,为所欲为。由于浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,"同源政策"是必须的,否则 Cookie 可以共享,互联网就毫无安全可言了。
受到同源限制:
(1)无法读取不同源的 Cookie、LocalStorage 和 IndexDB 。
(2)无法取得不同源的DOM 。
(3)不能向不同源的服务器发送ajax请求。
不受同源限制:
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以跨域加载资源,而不受同源策略的限制。
浏览器对跨域访问的判定:
CORS机制把跨域请求分为两类:简单请求和非简单请求。
(1) 请求方法是以下三种方法之一:HEAD、GET、POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
但凡不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的解决,是不一样的。
简单请求:
浏览器会带上Origin的请求头发送到服务器,服务器根据Origin判断能否许可。假如许可就会带上CORS相关想要头,假如不在许可范围内就不会带上CORS相关的响应头。浏览器再根据响应头中能否有相关的CORS响应头,来判断阻拦响应body和抛出错误。
非简单请求:
非简单请求会在发真正的请求之前发送一个OPTIONS的带着Origin、Access-Control-Request-Method、Access-Control-Request-Headers等CORS相关的请求头的预检请求到服务器,服务器确认可以这样请求,就会返回带着Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等CORS相关的响应头的响应,浏览器检查到相关的CORS响应头,说明通过预检可以继续发送真正的请求;服务器确认不可以,则不会返回这些相关响应头,浏览器没检查到CORS的响应头就会抛出错误。

关于跨域的几个问题

为什么a.wang.com访问wang.com也算跨域?
由于历史上,出现过不同的公司共用域名,a.wang.com和wang.com不肯定是同一个网站,浏览器谨慎起见,认为这是不同的源。
为什么不同端口也算跨域?
起因同上,一个端口一个公司的情况也不是没有的。
记住:安全链条的强度取决于最弱的一环,所有和安全相关的问题都要谨慎对待。
为什么两个网站的IP一样,也算跨域?
起因同上,由于IP也是可以共用的。
为什么可以跨域使用CSS、JS和图片等?
同源策略限制的是数据访问,我们引用CSS、JS和图片的时候,其实并不知道其内容,我们只是在引用。

处理方案1:跨域资源共享(CORS)

从原理上讲实现CORS通信的关键是服务器。只需服务器实现了CORS接口,即可以跨源通信。
服务器要给接口的响应头设置:Access-Control-Allow-Origin:*

处理方案2:JSONP跨域

我们在跨域的时候因为当前的浏览器不支持 CORS 或者者由于某些条件不支持 CORS,我们必需使用另外一种方式来跨域,于是我们就请求一个 JS 文件,这个 JS 文件会执行一个回调,回调里面就有我们需要的数据。

let script = document.createElement('script');script.src = 'http://www.wang.cn/login?username=wang&callback=callback';document.body.appendChild(script);function callback(res) {  console.log(res);}

JSONP跨域优点
兼容ie并实现跨域
JSONP跨域缺点
因为是 script 标签,所以读不到 ajax 那么准确的状态,不知道状态码是什么,也不知道响应头是什么,它只知道成功和失败。
不支持post(由于是 script 标签,所以只支持 get 请求)
手写jsonp
手写jsonp并返回Promise对象
参数url,data:json对象,callback函数
原理:<script>元素不受同源策略的影响,可以进行AJAX传输。当script元素访问时,返回由回调函数进行包裹的json数据。在回调函数中获取数据进行解决。

function jsonp(url, data = {}, callback = 'callback') {    // 解决json对象,拼接url    data.callback = callback    let params = []    for (let key in data) {        params.push(key + '=' + data[key])    }    console.log(params.join('&'))    // 创立script元素    let script = document.createElement('script')    script.src = url + '?' + params.join('&')    document.body.appendChild(script)    // 返回promise    return new Promise((resolve, reject) => {        window[callback] = (data) => {            try {                resolve(data)            } catch (e) {                reject(e)            } finally {                // 移除script元素                script.parentNode.removeChild(script)                console.log(script)            }        }    })}

调用方法
1、创立script元素,设置src属性,并插入文档中,同时触发AJAX请求。
2、返回Promise对象,then函数才行继续,回调函数中进行数据解决
3、script元素删除清除

jsonp('http://photo.sina.cn/aj/index', {  page: 1,  cate: 'recommend'}, 'jsoncallback').then(data => {  console.log(data)})

其余处理方案

如修改document.domain实现主域相同不同子域的框架间的交互等,在实际项目中都很少使用,这里不再赘述。

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】2FA验证器 验证码如何登录(2024-04-01 20:18)
【系统环境|】怎么做才能建设好外贸网站?(2023-12-20 10:05)
【系统环境|数据库】 潮玩宇宙游戏道具收集方法(2023-12-12 16:13)
【系统环境|】遥遥领先!青否数字人直播系统5.0发布,支持真人接管实时驱动!(2023-10-12 17:31)
【系统环境|服务器应用】克隆自己的数字人形象需要几步?(2023-09-20 17:13)
【系统环境|】Tiktok登录教程(2023-02-13 14:17)
【系统环境|】ZORRO佐罗软件安装教程及一键新机使用方法详细简介(2023-02-10 21:56)
【系统环境|】阿里云 centos 云盘扩容命令(2023-01-10 16:35)
【系统环境|】补单系统搭建补单源码搭建(2022-05-18 11:35)
【系统环境|服务器应用】高端显卡再度登上热搜,竟然是因为“断崖式”的降价(2022-04-12 19:47)
手机二维码手机访问领取大礼包
返回顶部