同源策略 & 高效调试CORS实现
# 目录
------------------------------------------------------------------------------------------------------------------
为什么有同源策略?
该策略允许在源自同一站点的页面上运行的脚本在没有特定限制的情况下访问彼此的数据,但阻止脚本访问存储在不同域中的数据。
所谓同源是指域名、协议、端口相同。
同源策略主要是为了安全,如果浏览器没有同源限制,那么:
① 某域下的Cookie等与该域相关的密切数据可以任意读取
② 不同域下DOM任意操作,篡改
③ 恶意网站能随意执行Ajax脚本偷取隐私数据
针对以上第③点:举个栗子:
用户正在访问银行网站B但未注销。然后用户转到另一个站点A,该站点在后台运行一些恶意JavaScript代码,该代码从银行站点B请求数据。由于用户仍然登录银行站点,恶意代码可以执行用户在银行站点B上执行的任何操作。
例如,它可以获得用户上次交易的列表,创建新交易等。这是因为浏览器可以基于银行站点的域向银行站点发送和接收会话cookie。
访问恶意站点的用户以为他访问的站点无法访问银行会话cookie。虽然恶意网站下JavaScript确实无法直接访问银行会话cookie,但它仍然可以通过银行网站的会话cookie向银行网站发送和接收请求。
同源策略在实施中需要解决的问题:
实现CORS (Cross-Origin Resource Sharing)
使用JSONP (JSON Padding)
Use postMessage method
建立一个本地代理服务器,这样先同源访问,由代理服务器转发请求
CORS跨域请求方案
CORS是一个服务器允许放松同源策略的W3C标准,服务器可以显式允许同源请求并且拒绝其他的非同源访问。
CORS标准描述了新的HTTP标头,它为浏览器提供了一种仅在获得许可时才能请求远程URL的方法。尽管服务器可以执行某些验证和授权,但浏览器通常负责支持这些标头并遵守它们所施加的限制。
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
举个橘子:
① 浏览器使用XmlHttpRequest发起跨域Ajax请求,浏览器会自动携带Origin请求
② 服务器有一套自己的的CORS逻辑,这个逻辑会在服务端响应头:Access-Control--*******--中体现
举例: Access-Control-Allow-Origin: */Origin/null // 该响应头会3种可能值
③ 浏览器会遵守Access-Control--*******-- 响应头对应值所施加的限制
GET /resources/public-data/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Referer: http://foo.example/examples/access-control/simpleXSInvocation.html Origin: http://foo.example HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 00:23:53 GMT Server: Apache/2.0.61 Access-Control-Allow-Origin: * Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: application/xml BODY
预检Preflight
对于可以修改数据的Ajax和HTTP请求方法(通常是GET以外的HTTP方法,或者某些MIME类型的POST用法),CORS规范要求浏览器“预检”请求,
使用HTTP OPTIONS请求方法从服务器请求支持的方法(由浏览器发起),然后,在服务器“批准”时,使用实际的HTTP请求方法发送实际请求。
上图描述了浏览器是是怎样决定使用【简单请求】还是 【预检XHR请求】
const invocation = new XMLHttpRequest(); const url = 'http://bar.other/resources/post-here/'; const body = '<?xml version="1.0"?><person><name>Arun</name></person>'; function callOtherDomain(){ if(invocation) { invocation.open('POST', url, true); invocation.setRequestHeader('X-PINGOTHER', 'pingpong'); invocation.setRequestHeader('Content-Type', 'application/xml'); invocation.onreadystatechange = handler; invocation.send(body); } } ...... // 以上使用POST 发送了一个xml,同时自定义了一个request header: X-PINGOTHER, 该跨域请求必定会触发浏览器预检行为
携带凭据跨域
默认情况下,浏览器在XMLHttpRequest请求中不会发送凭据 (凭据包括HTTP cookies 和 Http认证信息比如 Authorization头)。
访问的外站API需要授权,这时就涉及携带凭据跨域:
const invocation = new XMLHttpRequest(); const url = 'http://bar.other/resources/credentialed-content/'; function callOtherDomain(){ if(invocation) { invocation.open('GET', url, true); invocation.withCredentials = true; // 该标记设定在XMLHttpRequest中发送凭据 invocation.onreadystatechange = handler; invocation.send(); } }
GET /resources/access-control-with-credentials/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Referer: http://foo.example/examples/credential.html Origin: http://foo.example Cookie: pageAccess=2 HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:34:52 GMT Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2 X-Powered-By: PHP/5.2.6 Access-Control-Allow-Origin: http://foo.example // 当响应的是一个携带凭据的请求,服务端必须为Access-Control-Allow-Origin响应头指定一个Origin,而不能再用 * 通配符。 Access-Control-Allow-Credentials: true Cache-Control: no-cache Pragma: no-cache Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT // 设置新的Cookie Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 106 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain [text/plain payload]
需要注意:
以上携带请求凭据跨域,若响应头Access-Control-Allow-Origin被指定为“*”, 请求将报错; 也就是说 在携带凭据跨域的时候,服务器响应头不允许使用囫囵吞枣的* 通配符。
虽然浏览器提示报错;实际上浏览器会取得Response,但是浏览器会遵守CORS规范阻止你的代码访问响应体。
附:一种高效、优雅地调试CORS实现的方法
CORS规范很大程度体现了服务端对资源的安全策略, 作为后端开发人员,调试CORS规范不是一个简单的事情:
直观上:需要搭建跨域服务器、构建AJAX脚本请求。
Curl是一个利用URl规则在命令行下工作的文件传输工具,可以说是一款强大的http命令行工具。
curl "https://A.com/api/3.0/drilldown/query" -X OPTIONS -H "Access-Control-Request-Method: POST" -H "Origin: http://www.example.com.cn" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36" -H "Access-Control-Request-Headers: content-type" --verbose
-X 请求动词
-H 指定请求头
--verbose 输出详细内容

以上从为什么?怎么做?更高效的完成? 三方面讲述了CORS,希望对大家有所帮助。
感谢您的认真阅读,如有问题请大胆斧正,如果您觉得本文对你有用,不妨右下角点个或加关注。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置注明本文的作者及原文链接,否则保留追究法律责任的权利。
同源策略 & 高效调试CORS实现的更多相关文章
- 同源策略与 JSONP CORS
同源策略与 JSONP CORS 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以 ...
- Apache2 同源策略解决方案 - 配置 CORS
什么是同源策略 现在的浏览器大多配有同源策略(Same-Origin Policy),具体表现如下: 浏览某一网站,例如 http://www.decembercafe.org/.这个网页中的 Aja ...
- 同源策略jsonp和cors
同源策略: 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上 ...
- Django 之Ajax&Json&CORS&同源策略&Jsonp用法
什么是Json 定义: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.它基于 ECMAScript (w3c制定的js规范)的一个子集 ...
- [CORS:跨域资源共享] 同源策略与JSONP
Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...
- 关于安全性问题:(XSS,csrf,cors,jsonp,同源策略)
关于安全性问题:(XSS,csrf,cors,jsonp,同源策略) Ajax 是无需刷新页面就能从服务器获取数据的一种方法.它的核心对象是XHR,同源策略是ajax的一种约束,它为通信设置了相同的协 ...
- 浏览器的同源策略及CORS跨域解决方案 DRF
一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: UR ...
- AJAX_违反了同源策略_就是"跨域"——jsonp 和 cors
https 协议 默认端口号 443 http 协议 默认端口号 80 同源策略 由网景公司提出的——浏览器 的 为了浏览器安全而生 同源策略: 协议.域名.端口号 必须完全一致 违 ...
- 同源策略与CORS
同源策略 同源策略是浏览器保护用户安全上网的重要措施,协议.域名.端口号三者相同即为同源. 不同源下,浏览器不允许js操作Cookie.LocalStorage.DOM等数据或页面元素,也不允许发送a ...
随机推荐
- iview源码解析(1)
概述 公司技术栈开始用vue主导开发,但因为公司前端会vue的不多所以在项目中用到vue的技术不是很深,之前出去面试被接连打击,而且本来打算开始为公司vue的项目构建自己的组件库所以去下载了iview ...
- 分布式爬虫框架XXL-CRAWLER
<分布式爬虫框架XXL-CRAWLER> 一.简介 1.1 概述 XXL-CRAWLER 是一个分布式爬虫框架.一行代码开发一个分布式爬虫,拥有"多线程.异步.IP动态代理.分布 ...
- 同一台电脑上配置多个解压版tomcat方法(本例安装两个)
一.在环境变量中设置变量() CATALINA_HOME = tomcat路径一 CATALINA_BASE = tomcat路径一 CATALINA_HOME2 = tomcat路径二 CATALI ...
- Python并发编程之线程消息通信机制任务协调(四)
大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...
- .NET开发微信小程序-微信支付
前台MD5加密代码 /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algor ...
- Fiddler证书安装(查看HTTPS)
现在很多带有比较重要信息的接口都使用了安全性更高的HTTPS,而Fiddler默认是抓取HTTP类型的接口,要想查看HTTPS类型接口就需要安装fiddler证书. fiddler安装教程可参考: ...
- Python_heapq
import heapq #导入heapq堆模块 import random data = random.sample(range(1000),10) print(data) heapq.heapif ...
- 0516js综合练习
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- flock SUSE/RHEL
Util-linux-2.26 Util-linux 软件包其它实用程序.包括处理文件系统.控制台.分区以及消息等工具. 大概编译时间:1.3 SBU 需要磁盘空间:137 MB 6.65.1. FH ...
- RedHat Linux下iptables防火墙设置
一般情况下iptables已经包含在Linux发行版中.运行 # iptables --version 来查看系统是否安装iptables 启动iptables:# service iptables ...