1、说明

https://www.cnblogs.com/xuanyuan/p/12979841.html

该文基于故事图文并茂地讲述了跨域的前生今世,因为文章是故事形式,里面的一些要点都只是一提而过,下面再次总结一下,顺序就和该文讲述的顺序一致

本文参考文章有:

https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

https://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

2、浏览器的基本原理

浏览器的职责划分包括:

  1. 负责网络连接部分;
  2. 负责存储管理部分,管理 Cookie、LocalStorage 、SessionStorage 等;
  3. 网页渲染部分;
  4. JS引擎;

网页渲染负责把来自网络的HTML文件进行解析,构建DOM树,再拿CSS文件,构建CSSOM树,最后把网页划出来

网页在渲染的时候,遇到 <script> 标签,则需要JS引擎来处理,然后接着下面的渲染,这个很重要。因为在执行 JS 代码的时候,有可能会去修改构建的DOM树的内容,所以,一次性构建完DOM树,在执行 JS 代码是不可取的。

3、禁止跨域

当网页所在的URL和目标URL只要有协议、域名、端口其中一个不同,即算跨域,如下图所示

跨域会引起网络安全的问题,最典型的就是 CSRF攻击,即跨站请求伪造。

CSRF攻击的大致原理是钓鱼网站冒用正规网站的身份验证,使请求合理化,过程如下:

  1. 用户先打开浏览器,访问受信任的网站A,并使用正确的用户名和密码登陆网站A;
  2. 成功登陆网站A后,网站A产生Cookie信息并返回给浏览器,浏览器保存此Cookie;
  3. 用户未退出A网站,Cookie有效,同时,在同一个浏览器中打开了钓鱼网站B;
  4. B网站返回攻击性代码,并发出请求要求访问第三方网站A;
  5. 浏览器根据B的请求,在用户不知情待着保存的用户登陆A网站的Cookie,向网站A发出请求,此请求完全合法,网站A无法识别,导致被恶意攻击;

防止CSRF攻击的典型方法是生成验证token,本文不详述

3.1、禁止跨域导致的问题

因为跨域访问会导致类似的安全问题,所以有的公司就制定了禁止跨域访问的规定,但是禁止跨域访问就会导致一系列的问题。比如网页中的引入的外部css和js文件全部失效。

为了避免这种情况,这些公司就对跨域的请求进行一些修改,规定,引入外部文件的时候,可以忽略禁止跨域的限制,在前端中,就是所有带有 src 属性的元素都可以跳过跨域限制,比如 <img>、<script>、<link> 等,这样就解决了引入外部文件失效的问题

4、JSONP

随着技术的发展,web 开发流行前后端分离技术,前端不仅仅要展示静态页面,还需要向服务器请求数据动态展示,但是前端的网页和后端的接口经常不在一台服务器上,由于跨域的限制,前端使用AJAX的请求会被拒绝。

此时,有人就想到,前端带有 src 属性的元素可以跳过跨域的限制,可以利用这一特性,进行数据交互

首先,我们要知道,src 属性的资源请求是基于 HTTP 协议中的 GET 方法,因此,前端的请求就可以通过此方法传递到后端。

前端在请求的时候,预先写好数据处理的回调函数,将需要请求的参数和回调函数一起传递到后端,后端使用回调函数包裹需要的数据传到前端,即可完成一次通信。

此时发现,正好有一种JSON的数据格式,可以方便地描述数据,而且又是JS的原生数据类型,可以很方便地被前端解析,所以后端在处理的时候,使用回调函数包裹的数据使用JSON类型。

自此,前后端的数据传输有了一个非正式的传输协议,因为使用JSON格式,所以称之为 JSONP(JSON with Padding)

示例如下:

首先,前端能有请求静态资源

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<script type="text/javascript" src="http://server.com/test.js"></script>
</head>
</html>

上例中,服务端的 test.js 脚本能够请求到,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
var testFunction = function(data){
alert('客户端调用,数据为:' + data.data + "," + data.message);
};
</script>
<script type="text/javascript" src="http://server.com/test.js"></script>
</head>
</html>

后端的 test.js 内容如下:

testFunction({
"data": 1234,
"message": "OK"
});

示例中,testFunction() 函数定义好之后,接下来的标签请求后端的js脚本,得到之后,执行testFunction() 方法,数据也顺利传递进来了

然后,逐渐演化,后端的脚本也不用写死,因为src是GET方法,可以将回调函数直接传给后端,让后端解析

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
var testFunction = function(data){
alert('客户端调用,数据为:' + data.data + "," + data.message);
};
</script>
<script type="text/javascript" src="http://server.com?param=price&cllbask=testFunction"></script>
</head>
</html>

逐渐地,各大主流框架都有了 JSONP 的封装,这里不再一一列举,但是需要注意的事是,JSONP 虽然看起来和 Ajax 相似,但是本质上和 Ajax 是两种不同的方式

5、CORS

有了 JSONP,跨域的问题暂时解决了,但是 JSONP 怎么看都是一种取巧的技术,使用起来会有很多的限制,比如只能使用 GET 方法,调用失败也不会返回错误等

后来,浏览器厂商推出了 CORS(Cross-origin resource sharing) 技术,CORS 是一种浏览器机制,它使用 HTTP 的协议头来允许不同服务器的请求

CORS 的大致方式是,在正式的请求之前,先发一个 OPTION 请求,询问服务器是允许接下来的跨域请求。约定,在 OPTION 请求中新增几个字段

  • Origin: 发起请求原来的域;

  • Access-Control-Request-Method: 将要发起的跨域请求方式(GET/POST等);

  • Access-Control-Request-Headers: 将要发起的跨域请求中包含的请求头字段

服务器在 OPTION 请求的 response 中表明是否允许此跨域

  • Access-Control-Allow-Origin: 允许的域(*表示所有域)
  • Access-Control-Allow-Method: 允许哪些请求方式(GET/POST等)
  • Access-Control-Allow-Headers: 允许哪些请求头字段
  • Access-Control-Allow-Credentials: 是否允许携带Cookie

如下图所示

浏览器接受到服务器的 response 后,检查,如果不符合要求,就拒绝接下来的请求

然而,每次请求都先发起一次 OPTION 预请求费时费力费资源,因此,又约定,有两种方式,可以避免预检请求:

一是 简单请求,即不会触发 CORS预检请求的请求。符合下面所有条件的请求,即为简单请求:

  1. 使用的方式为 GET/POST/HEAD 其中之一;
  2. HTTP 请求头中不超过以下五种字段:
    1. Accept
    2. Accept-Language
    3. Content-Language
    4. Last-Event-ID
    5. Content-Type
  3. Content-Type 的值仅限于以下三者之一:
    1. text/plain
    2. multipart/form-data
    3. application/x-www-form-urlencoded

二是,在前一次请求之后,服务器的 response 中会带有一个 Access-Control-Max-Age ,表明这个询问的有效期,浏览器的请求在有效期内的,也可不进行预检请求

6、CORS和JSONP的比较

CORS 和 JSONP 的方式不同,但是目的相同,CORS 的功能比 JSONP强大太多

JSONP 因为使用 src 值来请求,所以只支持 GET 方法,而 CORS 支持所有类型的 HTTP请求

但是,JSONP 可以支持老式的浏览器,还可以向不支持 CORS 的服务器请求数据

CORS小结的更多相关文章

  1. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  2. 小结ajax中的同源和跨域 jsonp和cors

    网上的同源和跨域一般都比较复杂,最近也稍微总结了一下: 所谓同源,是浏览器的一种安全机制,作用在于保护网页数据的安全,不同源的网页之间不允许cookie dom ajax等行为 同源的条件:1.协议相 ...

  3. AJAX POST&跨域 解决方案 - CORS

    一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴.          跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是 ...

  4. C#进阶系列——WebApi 跨域问题解决方案:CORS

    前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题.本篇主要从实例的角度分享下CORS解决跨域问题一些细节. WebApi系列文章 C#进阶系列— ...

  5. WeX5 - AJAX跨域调用相关知识-CORS和JSONP

    http://docs.wex5.com/ajax-cross-domain/ 1.什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容 ...

  6. js中各种跨域问题实战小结(一)

    什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略 ...

  7. AJAX跨域调用相关知识-CORS和JSONP(引)

    AJAX跨域调用相关知识-CORS和JSONP 1.什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容. 但是我们项目开发过程中,经常 ...

  8. AJAX POST&跨域 解决方案 - CORS(转载)

    跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免 ...

  9. AJAX跨域调用相关知识-CORS和JSONP

    1.什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容. 但是我们项目开发过程中,经常会遇到在一个页面的JS代码中,需要通过AJAX去 ...

  10. jsonp与cors跨域的一些理解(转)

    CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而这种访问是被同源策略所禁止的. ...

随机推荐

  1. #2102:A计划(DFS和BFS剪枝搜索)

    题意: 有几个比较坑的地方总结一下, 很容易误解: 遇到#就必须走 #不消耗时间 #对面如果也是#也不能走, 要不然无限循环了 最短路径剪枝时, 发现不能走的#是要把两步都标注为-1并跳出 题解: 一 ...

  2. #2066:一个人的旅行(Dijkstra算法入门题)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  3. POJ - 1611 : The Suspects (普通并查集)

    思路: 模板题,一步一步加入集合,最后判断有多少人跟0在同一个集合就行了. #include<iostream> #include<cstdio> using namespac ...

  4. “n个球放到m个盒子”问题整理(Twelvefold way)

    这个算法的正式名字是:"Twelvefold way",共用12种情况. 本文转载自:自为风月马前卒的博文:浅谈"n个球"和"m个盒子"之间 ...

  5. 阿里云 FaaS 架构设计

    摘要:希望通过本系列课程,让大家更深入了解阿里云FaaS架构设计,以及神龙高密部署的FaaS介绍. 本篇内容将从2个部分为读者介绍关于阿里云 FaaS 架构设计和神龙高密部署的 FaaS,希望可以让大 ...

  6. winform 各种小功能

    1.  实现待查询功能的combox private void Frm_Main_Load(object sender, EventArgs e) { cbox_Find.Items.Clear(); ...

  7. 神经网络优化篇:详解学习率衰减(Learning rate decay)

    学习率衰减 加快学习算法的一个办法就是随时间慢慢减少学习率,将之称为学习率衰减,来看看如何做到,首先通过一个例子看看,为什么要计算学习率衰减. 假设要使用mini-batch梯度下降法,mini-ba ...

  8. [转帖]Prometheus 监控之 Blackbox_exporter黑盒监测 [icmp、tcp、http(get\post)、dns、ssl证书过期时间]

    Blackbox_exporter 主动监测主机与服务状态 Prometheus 官方提供的 exporter 之一,可以提供 http.dns.tcp.icmp 的监控数据采集 官方github: ...

  9. [转帖]time_zone 是怎么打爆你的MySQL的

    https://plantegg.github.io/2023/10/03/time_zone%E6%98%AF%E6%80%8E%E4%B9%88%E6%89%93%E7%88%86%E4%BD%A ...

  10. [转帖]Oracle中有大量的sniped会话

    https://www.cnblogs.com/abclife/p/15699959.html 1 2 3 4 5 6 7 SQL> select status ,count(*) from g ...