​每次遇到跨域、代理、CORS这几个词都懵懵的,我决定一次把他们都搞明白,以后遇到他们再也不用害怕了。

一、什么是同源策略?

同源策略是在1995年由 Netscape公司引入到浏览器的,目前所有浏览器都支持,它是浏览器最重要的安全保障,目的是严格管理不同网站间相互的资源访问(严格来说是不同“源”之间)。

什么是“源”,“源”是指:协议+域名+端口号,这三个必须都相同,才算是同源。假设我们的网站是:http://www.abc.com,那么:

http://www.abc.com/a 同源(与路径无关)
http://www.abc.com:80 同源(80端口是http默认端口)
http://www.Abc.com 同源(url忽略大小写)
https://www.abc.com 不同源(协议不同)
http://www.abc.com:81 不同源(端口不同)
http://abc.com 不同源(域名不同)
http://api.abc.com 不同源(域名不同)
http://api.www.abc.com 不同源(域名不同)
http://220.188.32.45:80 不同源(自己服务器的IP也不行)

注意,同源策略只存在于浏览器之中,服务端发出的HTTP请求是不受限制的。

二、跨源不止AJAX

提到跨域(跨源),一般都是我们在写AJAX的时候会涉及。其实,web中还有很多别的行为也会跨域,浏览器对这些行为有不同的默认处理方式,常见的有以下这些(注意,浏览器的处理方式未经严格验证,仅供参考):

<script>、<link>、<img>、<video>、<object>、background的url() 根据我们的经验,对这些浏览器是允许跨域访问的,css好像需要设置一下content-type,这个用到时再说
@font-face引入字体 这个部分浏览器是不支持跨域的,需要CORS
cookie 可以通过把cookie写入到一级域名,二级域名就可以访问了,其余情况不允许
localStorge和indexDB 不允许跨域
form提交 允许跨域
AJAX 不允许跨域
<iframe> 过时的东西,不讨论了

三、为什么需要同源策略?

我是这么理解的:网站获取自己的资源当然没问题,可如果想拉取其他网站的资源,这种行为等于“偷”啊!你用我的浏览器去“偷”人家的东西,那万一出了事,我是要承担责任的!那可不行,我得禁止你“偷”人家的东西,于是就有了同源策略。

以下我们只讨论AJAX。并且其实AJAX跨域也有:JSONP、WebSocket、CORS三种方法,由于本人只对CORS感兴趣,所以只讨论CORS。

四、什么是CORS?

很显然,完全禁止跨源也不行啊,现在很多应用前端和服务本来就不在一个服务器上。那怎么办呢?除非,服务器你自己告诉我,这个资源允不允许这个源访问。怎么告诉我呢?在响应头里。这种通过允许服务器自定义不同源对自己资源的访问权限,然后浏览器据此来拦截或放行的方式,就叫CORS。

这儿我们可以得到一个重要的信息,就是浏览器拦截跨域请求,是在响应阶段,也就是响应返回到浏览器之后,再决定是否拦截。自然会产生的疑问是,为什么不在请求阶段就拦截呢?在请求阶段就拦截的话,如何知道服务器那边到底允不允许呢?这样等于彻底禁止了跨域资源请求,显然不行。

四、简单请求和复杂请求

浏览器把跨域的AJAX分为:简单请求和复杂请求。具体定义如下,同时满足以下3项(其实还有其他2项,只是一般用不到)要求的,就是简单请求,其余的都是复杂请求:

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Accept-Encoding
  • Content-Language
  • Content-Type

(3)Content-Type只限于以下三个值:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

是不是有点眼熟?这三种Content-Type正是Form表单的三种数据提交格式。这主要是因为,在没有AJAX的时代,我们通过Form表单的方式来提交数据,做过Form表单提交的同学都知道,这个是允许跨域的。所以为了向前兼容,浏览器就把Form表单可以模拟的AJAX称为简单请求,反之就是复杂请求。

关于这个其实有更深层次的理解,大家可以在知乎搜索“为什么跨域的post请求区分为简单请求和非简单请求和content-type相关?”,看看“贺师俊”大佬的回答。

与简单请求不同的是,复杂请求会在正式请求之前,先发送一个OPTIONS请求到服务器,称为“预检”,在获得服务器的允许后,才会发送正式请求。

五、什么是预检请求?

那么问题来了,既然是响应阶段才拦截,也就是说,不管这个跨域访问服务器允不允许,都不影响它真实的到达服务器,在服务器“兜了一圈”。如果这个请求是GET还好,只不过是来“观光”的,不会产生啥影响,但如果是POST、PUT之类的请求,本身往往是会修改服务器资源的,即便响应结果在到达浏览器后被拦截了,对服务器的影响也已经发生了,无法挽回了。虽然服务器也可以写代码直接拒绝这些请求,但浏览器不能指望服务器自己把这些都做好啊。那怎么办呢?浏览器也有办法,在发出真实请求之前,先发一个“预检请求”,先问服务器这个请求是否被允许?服务器允许之后,才发送正式请求。这种方式,就叫“预检”。

六、预检请求能不能省了?

如果每次复杂请求都要先发送一次预检,也太麻烦了。很自然的会想,有没有办法来避免每次都要预检?有办法,服务器可以在OPTIONS请求的响应里加一个Access-Control-Max-Age响应头,告诉浏览器这个预检的结果可以被缓存多久。比如Access-Control-Max-Age:86400,则在一天之内,对同一个请求,浏览器不用重复发送预检请求了。什么?你想再简单一点,能不能告诉浏览器“这个网站朕准了,发送一次之后都不用发送预检了”?抱歉,做不到。预检能省来源于浏览器对预检请求结果的缓存,而这个缓存的键,是:URL+请求方法+请求头。所以,只能针对单个请求,利用缓存在一定时间内只发送一次预检。

以上是我对跨域和CORS的理解,有错误之处欢迎指出,非常感谢!

重学HTTP:理解同源策略和CORS的更多相关文章

  1. 浏览器的同源策略及CORS跨域解决方案 DRF

    一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: UR ...

  2. 同源策略与CORS

    同源策略 同源策略是浏览器保护用户安全上网的重要措施,协议.域名.端口号三者相同即为同源. 不同源下,浏览器不允许js操作Cookie.LocalStorage.DOM等数据或页面元素,也不允许发送a ...

  3. 同源策略、CORS

    一.同源策略 同源策略(Same origin policy) 是一种约定, 它是浏览器最核心也是最基本的安全功能 , 如果缺少了同源策略, 则浏览器的正常功能可能都会受影响 , 可以说web是构建在 ...

  4. 同源策略与CORS跨域请求

    一.同源策略 1.简介 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源 ...

  5. 同源策略 - JSONP - CORS

    1.  Jquery 对象可以通过 .index() 进行取出自当前元素在父级元素中存放的索引: 2. 浏览器的同源策略 -- Ajax 在访问非本网站的时候,在数据返回的时候,会被浏览器拦截 - 后 ...

  6. JSONP跨域的script标签请求为什么不受同源策略的限制?

    在复习跨域的时候,复习到了JSONP跨域,大家都知道JSONP跨域是通过动态创建script标签,然后通过其src属性进行跨域请求的,前端需要一个数据处理的回调函数,而服务端需要配合执行回调函数,放入 ...

  7. [CORS:跨域资源共享] 同源策略与JSONP

    Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...

  8. Apache2 同源策略解决方案 - 配置 CORS

    什么是同源策略 现在的浏览器大多配有同源策略(Same-Origin Policy),具体表现如下: 浏览某一网站,例如 http://www.decembercafe.org/.这个网页中的 Aja ...

  9. 关于安全性问题:(XSS,csrf,cors,jsonp,同源策略)

    关于安全性问题:(XSS,csrf,cors,jsonp,同源策略) Ajax 是无需刷新页面就能从服务器获取数据的一种方法.它的核心对象是XHR,同源策略是ajax的一种约束,它为通信设置了相同的协 ...

  10. 同源策略 & 高效调试CORS实现

    # 目录 为什么有同源策略? 需要解决的问题 CORS跨域请求方案 preflight withCredentials 附:高效.优雅地调试CORS实现 ----------------------- ...

随机推荐

  1. 2021-05-01:给定一个有序数组arr,代表坐落在X轴上的点。给定一个正数K,代表绳子的长度。返回绳子最多压中几个点?即使绳子边缘处盖住点也算盖住。

    2021-05-01:给定一个有序数组arr,代表坐落在X轴上的点.给定一个正数K,代表绳子的长度.返回绳子最多压中几个点?即使绳子边缘处盖住点也算盖住. 福大大 答案2021-05-01: 滑动窗口 ...

  2. openstack部署2

    检查服务,查看dashboard页面有哪些功能 检查服务状态 检查计算节点,控制节点服务是up状态 检查网络节点是True的状态.这里的每个计算节点,都是一个neutron的客户端. 查看dashbo ...

  3. Django4全栈进阶之路4 APP注册

    在 Django 4 中,应用(app)的注册是通过在项目的 settings.py 文件中添加应用名称来实现的.具体步骤如下: 在项目的根目录下创建一个应用目录,该目录应包含一个 apps.py 文 ...

  4. 修改本地hosts

    本地hosts文件地址 C:\Windows\System32\drivers\etc 修改前 修改后 可以使用记事本打开hosts文件或使用Notepad++ 工具打开 按图示添加,修改即可

  5. Must use destructuring props assignmenteslint

    eslint 检测提示Must use destructuring props assignmenteslint 使用对象结构就可以解决了

  6. SQL生成序号的四种方式

    排名函数是SQL SERVER2005新增的函数.排名函数总共有四种,分别是:row_number.rank. dense_rank .ntile. row_number:顺序生成序号. rank:相 ...

  7. Simple Date Format类到底为啥不是线程安全的?

    摘要:我们就一起看下在高并发下Simple Date Format类为何会出现安全问题,以及如何解决Simple Date Format类的安全问题. 本文分享自华为云社区<[高并发]Simpl ...

  8. “AI Earth”人工智能创新挑战赛:助力精准气象和海洋预测Baseline[1]、NetCDF4使用教学、Xarray 使用教学,针对气象领域.nc文件读取处理

    1."AI Earth"人工智能创新挑战赛:助力精准气象和海洋预测Baseline[1].NetCDF4使用教学.Xarray 使用教学,针对气象领域.nc文件读取处理 比赛官网: ...

  9. 【前端方案】-表格排序列LRU缓存方案

    目标: 排序后的表格列,页面刷新或者用户重新登录后,能够保持之前的操作排序 完成效果: 解决方案: 利用localstorage对排序后的表格列属性进行存储,页面刷新或者用户重新进入该页面时都先从lo ...

  10. CKS 考试题整理 (09)-日志审计 log audit

    Task 在cluster中启用审计日志.为此,请启用日志后端,并确保: 日志存储在 /var/log/kubernetes/audit-logs.txt 日志文件能保留 10 天 最多保留 2 个旧 ...