cors跨域探讨
前端跨域
前端跨域方案很多,jsonp
、iframe
等等,但是个人觉得,最正宗,最无损的跨域方式还是CORS
。
CORS
(Cross-origin resource sharing
)是一个W3C标准,翻译过来是跨域资源共享。
它允许浏览器向跨域(协议、域名、端口任一不相同)服务器发送XMLHttpRequest
请求。
目前支持所有现代浏览器(>IE10)
借阅了阮一峰大神的《跨域资源共享 CORS 详解》,结合自己的理解,说一说自己的CORS
的领会。
简介
CORS
协议本身,可以说,完全是由浏览器执行的。
对前端开发者而言,CORS
是在浏览器检查到跨域请求的时候,自动发起的。
对后台开发者而言,只要在headers
中返回特定的信息(相当于白名单)–具体的CORS
步骤,浏览器会根据headers
中返回的信息做出具体的行为。
请求
浏览器会自动将请求分为两类:简单请求、非简单请求。 只要同时满足以下条件,就属于简单请求。
(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
,标识请求来源。
这时候,服务器需要携带Access-Control-Allow-Origin
返回,并且里面的值包含origin
,浏览器才会允许xhr
获取返回的内容。
一条简单的跨域请求就完成了:
前端不需要写任何东西。
后台也可以不做任何逻辑处理,一律返回Access-Control-Allow-Origin
。
全部的CORS
把关工作都在浏览器端正式执行。
同时,发起跨域请求的时候,默认是不带cookie
的,需要手动开启,后台也需要权限允许。
一个简单的跨域样例如下:
非简单请求
当浏览器判定是非简单请求的时候,会在发正式请求前,想同一地址发起一个options
的预请求。
预请求携带了正式请求的方法(method)和特殊头(headers)。
Access-Control-Request-Method: POST,
Access-Control-Request-Headers: CARVEN
然后服务器返回自己允许的方法(method)和特殊头(headers),当然还有允许域
Access-Control-Allow-Method: POST, PUT
Access-Control-Allow-Headers: CARVEN, ZJY
Access-Control-Allow-Origin: http://localhost:63342
然后浏览器会比较,如果请求发起内容–origin
,method
,headers
,都在服务器响应的名单里,正式请求就可以发起了,流程再次回归到简单请求.
为什么会有非简单请求?
对于非简单(偏激理解为 危险)的请求,做到询问与逻辑代码的隔离。
比如:PUT、DELETE等method,从规范来说,会使目标地址发生增、删等行为,使目标服务器资源发生改变。
所以,浏览器会发起正式请求前,先向发起一次预请求,等到允许后再发正式请求。
控制CORS
在ES6的fetch中,已经可以控制cors
开关了。
fetch(url,{ mode: mode})
- mode=same-origin,不支持跨域,直接在浏览器端拦截跨域请求
- mode=no-cors,不执行跨域协议,即不存在跨域问题,即使有特殊header,也不发options。 但是只支持HEAD、GET、POST,且代码不能接收到响应信息。
- mode=cors,默认,执行cors协议。
结尾
前面举的实行例子,只是最简单的cors
规则演示,但其实,前后台手动通过获取headers
上携带的各种信息,可以很灵活的做其他的逻辑处理。
- 执行计划变化导致CPU负载高的问题分析 (r8笔记第20天)
- 数据结构基础(2) --顺序查找 ; 二分查找
- 数据结构基础(1) --Swap ; Bubble-Sort ; Select-Sort
- 使用 Go 语言完成 HTTP 文件上传与下载
- 运维平台的建设思考-元数据管理(四)(r8笔记第16天)
- JavaWeb21-基础加强(注解;代理;类加载器;泛型反射
- MySQL迁移文件的小问题(r8笔记第18天)
- SpringMVC学习第一天
- 最近的几个技术问题总结和答疑 (r8笔记第19天)
- Hibernate_day04总结
- Hibernate_day03总结
- 服务器进程异常的原因分析(第二篇)(r8笔记第16天)
- 最近处理的几个小问题_20160311 (r8笔记第35天)
- Hibernate_day02总结
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 搞它!!!linux服务器硬件及RAID 配置实战
- 认识XML
- 基于oracle的sql(结构化查询语言)指令
- oracle约束条件
- oracle常用函数介绍
- 搞它!!!Linux系统中查看进程和计划任务管理
- 搞它!!!深入了解linux文件系统底层原理及日志文件介绍
- 搞它!!!Linux系统MBR分区和GPT分区的区别
- oracle补充
- 搞它!!!Linux系统LVM原理及磁盘配额(PV、VG、LV、PE的关系,手把手教你,嘴对嘴的传达)
- 搞它!!!linux网络服务基本设置命令合集
- 搞它!!!Linux系统上DHCP服务器的配置(理论加实验,分分钟搞定!!!)
- 搞它!!!Linux——引导、排障及修复
- 排障集锦:九九八十一难之第一难!linux发现交换文件无法打开文件!
- 排障集锦:九九八十一难之第三难!搭建DNS错误:Host xxxx not found: 2(SERVFAIL)