## 同源策略
**同源策略**是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
如果两个 URL 的 protocol、port都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)
下表给出了与 URL `http://a.b.com/dir/page.html` 的源进行对比的示例:
| URL | 结果 | 原因 |
| --- | --- | --- |
| http://a.b.com/dir2/other.html | 同源 | 只有路径不同 |
| http://a.b.com/dir/inner/another.html| 同源 | 只有路径不同 |
| https://a.b.com/secure.html | 失败 | 协议不同 |
| http://a.b.com:81/dir/etc.html | 失败 | 端口不同 (http:// 默认端口是80) |
| http://c.b.com/dir/other.html | 失败 | 主机不同 |
---
## 跨域请求
CORS即Cross Origin Resource Sharing(跨来源资源共享)。
所谓的跨域访问或者跨域请求,就是是指通过 js 在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
但不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
## 解决方案
### jsonp
**JSONP原理:动态创建script标签,使用script的src进行跨域**
**具体步骤:**
1. 判断请求的与当前页面域是否同源,如果同源正常发送ajax,如果不同源,生成一个script标签
2. 生成一个随机的callback名字,并生成对应名字的方法。
3. 设置script的src为要请求的接口,将callback参数拼接在后面。
4. 后端接收到请求后,开始准备要返回的数据
5. 后端拼接数据,将要返回的数据用callback包裹起来,将内容返回。
6. 浏览区接收到内容那个,会当做js代码来执行。
7. 从而执行第二步生成的方法,这样就接收到后端返回给我们的对象。
由于jsonp的原理就是使用script标签进行跨域,而script都是使用get方式请求数据。所以jsonp跨域只能是get方法,即使你设置的post方法,jQuery也会自动转为get方法。
### CROS
1. 跨域资源共享是一份浏览器技术的规范,以避开浏览器的同源策略,是 JSONP 模式的现代版。
2. CORS背后的思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
3. 与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让前端工程师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好;另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。
具体做法:客户端不需要做什么,只需要在服务器端发送一个响应头即可:‘Access-Control-Allow-Origin’;
1. 如若允许所有域访问:Access-Control-Allow-Origin: \*;如:header("Access-Control-Allow-Origin: \*");
2. 如若只允许指定域访问:Access-Control-Allow-Origin: 域名A;如:header("Access-Control-Allow-Origin: http://www.test2.com");
CORS分为两种
1、**简单请求**
2、**复杂请求**
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
**凡是不同时满足上面两个条件,就属于非简单请求。**
浏览器对这两种请求的处理,是不一样的。
Access-Control-Allow-Origin: http://www.test.com
Access-Control-Max-Age: 3628800
Access-Control-Allow-methods: GET, PUT, DELETE, POST
Access-Control-Allow-Header: content-type
Access-Control-Allow-Credentail: true
“Access-Control-Allow-Origin"表明它允许” http://www.test.com "发起跨域请求
"Access-Control-Max-Age"表明在3628800秒内,不需要再发送预检验请求,可以缓存该结果(上面的资料上我们知道CROS协议中,一个AJAX请求被分成了第一步的OPTION预检测请求和正式请求)
"Access-Control-Allow-Methods"表明它允许GET、PUT、DELETE的外域请求
"Access-Control-Allow-Headers"表明它允许跨域请求包含content-type头
"Access-Control-Allow-Credentials"表明它允许cookies
---
**复杂请求**表面上看起来和简单请求使用上差不多,但实际上浏览器发送了不止一个请求。其中最先发送的是一种"预请求",此时作为服务端,也需要返回"预回应"作为响应。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。
预请求以OPTIONS形式发送,当中同样包含域,并且还包含了两项CORS特有的内容:
> Access-Control-Request-Method – 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。
> Access-Control-Request-Headers – 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部。
显而易见,这个预请求实际上就是在为之后的实际请求发送一个权限请求,在预请求回应返回的内容当中,服务端应当对这两项进行回复,以让浏览器确定请求是否能够成功完成。
> Access-Control-Allow-Origin(必含) – 和简单请求一样的,必须包含一个域。
> Access-Control-Allow-Methods(必含) – 这是对预请求当中Access-Control-Request-Method的回复,这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法,但服务端仍然可以返回所有允许的方法,以便客户端将其缓存。
> Access-Control-Allow-Headers(当预请求中包含Access-Control-Request-Headers时必须包含) – 这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。这里在实际使用中有遇到,所有支持的头部一时可能不能完全写出来,而又不想在这一层做过多的判断,没关系,事实上通过request的header可以直接取到Access-Control-Request-Headers,直接把对应的value设置到Access-Control-Allow-Headers即可。
一旦预回应如期而至,所请求的权限也都已满足,则实际请求开始发送。
- 序言
- 从业感悟
- 常用名词
- HTML
- JS
- ES6新特性
- jquery和vue对比
- 彻底理解this
- JQuery添加自定义函数
- js的实现
- 原始值和引用值
- MYSQL
- 简介
- 术语
- 特点
- 范式
- 数据类型1
- 数据类型2
- 编码
- 权限管理
- 事务
- mvvc
- 引擎
- MyISAM与InnoDB区别
- 索引类型
- 锁
- 死锁
- 分层架构
- 执行计划
- join原理
- 高可用
- 日志类型
- 分库分表
- 中间件
- 服务器
- 操作系统
- 信号量 锁 队列
- PHP
- composer加载原理
- composer基础知识
- 自动加载函数
- composer加载代码
- composer 自动加载
- 内存管理
- PHP执行流程
- cgi,fastCgi,php-fpm
- HTTP
- 错误码
- 跨域请求
- 面试
- 安全
- HTTP劫持
- 设计模式
- 如何正确的使用设计模式
- 单例模式
- 原型模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 建造者模式
- 设计原则
- 算法
- PHP短标签