同源策略

  浏览器最基本的安全规范——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的浏览器脚本(javascript、ActionScript、canvas)在没明确授权的情况下,不能读写对方的资源

  同源策略规定了 浏览器脚本互操作web数据的基本原则。

若没有这一基本原则,那么:

① 某域下DOM元素被另一方任意操作、篡改, 导致页面显示失控

② 某域下的Cookie等与该域相关的密切数据可以任意读取,导致与该域密切相关的浏览器cookie片段可能失真

③ 恶意网站能随意执行Ajax脚本偷取隐私数据,导致该域下核心业务数据被抓取。

同源策略在实施中面临的问题

默认的同源策略 限制了脚本互操作其他域的能力,大棒一挥, 关闭了A站脚本正常访问B站数据的需求

所以有以下变通方法:

① 实现CORS (Cross-Origin Resource Sharing) :

② 使用JSONP (JSON Padding)

③ 建立一个本地代理服务器,这样先同源访问,由代理服务器转发请求

以上①CORS是w3C 对于跨域请求推出的明确方案;②③方式都是一种Hack行为。

CORS跨域请求方案

W3C推出的跨域请求方案: 让web服务器明确授权 非同源页面脚本来访问自己, 以Response 特定标头 Access-Control-****-****  体现;   目前现代浏览器均认可并支持这些标头。

CORS新HTTP标头,为浏览器提供了在获得许授权,脚本才能访问其他域名页面数据的通道。

常规的携带Cookie Ajax跨域Get请求

const invocation = new XMLHttpRequest();
const url = 'http://bar.other/resources/credentialed-content/'; function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true; // Ajax请求默认不会发送凭据, 这里设定在Ajax跨域请求中发送凭据
invocation.onreadystatechange = handler;
invocation.send();
}
}

CORS规范

① 浏览器发起CORS或POST请求,浏览器会自动携带Origin标头(指示请求来自于哪个站点)

② Web服务器实现跨站访问授权逻辑, 授权结果在Response中以 Access-Control--******* 标头体现

最常见的Access-Control-Allow-Origin标头包含  * / Origin /null  三种响应值;

当请求是携带凭据的跨域请求,不可囫囵吞枣地指定为*通配符,而必须指定特定Origin

③ 浏览器会遵守Access-Control--*******-- 标头值所施加的跨域限制

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-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
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]

以上表示了一个常见的携带Cookie跨域Ajax Get请求, 其中 Access-Control-Allow-Credentials: true 指令浏览器可以将跨域请求的 Response 结果暴露给页面。

预检Preflight

对于非简单Ajax请求(通常是GET以外的HTTP方法,或者某些MIME类型的POST用法),CORS规范要求发起 "预检" 请求。

不过,这个请求不需要你手动发起,浏览器会自动使用OPTIONS请求方法从服务器请求支持的方法,然后,在服务器“批准”时,使用实际的HTTP请求方法发送实际请求。

下图显示 浏览器判断 非简单请求的逻辑图:

下面使用POST动作发起Ajax跨域请求,同时自定义了一个request header: X-PINGOTHER, 该请求触发浏览器预检行为

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);
}
}

程序员调试CORS的苦恼

跨域请求发生在A--->B 两站,作为某一方开发人员,调试CORS相对麻烦。

经过本StackOverFlow工程师的检索,curl 工具可优雅高效模仿Ajax跨域请求:

#  http://example.com 向谷歌站点发起一个跨域Get请求

curl -H "Origin: http://example.com" --verbose \ https://www.googleapis.com/discovery/v1/apis?fields=

从浏览器Network,将请求格式 以cUrl形式拷贝出来,改改。

总结

①  浏览器同源策略 作用对象是 浏览器脚本;

②  存在跨域请求的场景,某些方案是Hack行为;

③  W3C推出的CORS 是标准的跨域请求方案,思路是 在服务端Response标头体现 授权, 浏览器遵守该授权标头。

④  对于非简单的脚本跨域请求,浏览器会自动发起 Option请求预检, 大部分时候无需关注

⑤ 提供curl 工具帮助高效、优雅调试CORS。

后面会介绍浏览器的另一个有用的安全策略: Cookie SameSite策略。

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

https://stackoverflow.com/questions/12173990/how-can-you-debug-a-cors-request-with-curl/12179364#12179364

https://curl.haxx.se/docs/manpage.html

看后端程序员调试CORS的姿势的更多相关文章

  1. 后端程序员实现一个IP归属地的小程序

    在日常开发中,后端主要提供数据以及处理业务逻辑,前端主要提供页面布局以及数据展示.后端程序员对于页面布局接触比较少,但是小程序有完善的文档说明.页面布局也相对简单,实现起来相对简单一些.而且小程序相对 ...

  2. 写给后端程序员的HTTP缓存原理介绍

    There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Ka ...

  3. 科普,想成为厉害的 Java 后端程序员,你需要懂这 13 个知识点

    老读者就请肆无忌惮地点赞吧,微信搜索[沉默王二]关注这个在九朝古都洛阳苟且偷生的程序员.本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题. 站 ...

  4. 科普,想成为厉害的 Java 后端程序员,你需要懂这些

    站在运筹帷幄的角度来看,一名厉害的 Java 后端程序员都需要懂得哪些知识呢?我想,这也是很多读者迫切想知道的一个问题,因为如果不站在一个宏观的角度的话,所有学过的知识点都是零散的,就感觉像一只迷路的 ...

  5. 后端程序员必备的 Linux 基础知识

    1. 从认识操作系统开始 正式开始 Linux 之前,简单花一点点篇幅科普一下操作系统相关的内容. 1.1. 操作系统简介 我通过以下四点介绍什么是操作系统: 操作系统(Operating Syste ...

  6. Angular学习资料大全和常用语法汇总(让后端程序员轻松上手)

    前言: 首先为什么要写这样的一篇文章呢?主要是因为前段时间写过一些关于Angualr的相关实战文章,有些爱学习的小伙伴对这方面比较感兴趣,但是又不知道该怎么入手(因为认识我的大多数小伙伴都是后端的同学 ...

  7. java后端程序员1年工作经验总结

    java后端1年经验和技术总结(1) 1.引言 毕业已经一年有余,这一年里特别感谢技术管理人员的器重,以及同事的帮忙,学到了不少东西.这一年里走过一些弯路,也碰到一些难题,也受到过做为一名开发却经常为 ...

  8. Java后端程序员都做些什么?

    这个问题来自于QQ网友,一句两句说不清楚,索性写个文章. 我刚开始做Web开发的时候,根本没有前端,后端之说. 原因很简单,那个时候服务器端的代码就是一切:接受浏览器的请求,实现业务逻辑,访问数据库, ...

  9. 精干货! Java 后端程序员 1 年工作经验总结

    一.引言   毕业已经一年有余,这一年里特别感谢技术管理人员的器重,以及同事的帮忙,学到了不少 东西.这一年里走过一些弯路,也碰到一些难题,也受到过做为一名开发却经常为系统维护 和发布当救火队员的苦恼 ...

随机推荐

  1. 怎样退出App之前唤醒还有一个App?

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 SDK并没 ...

  2. android lanchmode

    http://www.cnblogs.com/xiaoQLu/archive/2012/07/17/2595294.html http://www.cnblogs.com/lwbqqyumidi/p/ ...

  3. 基于EasyIPCamera实现的数字网络摄像机IPCamera的模拟器IPC RTSP Simulator

    还记得去年在北京安博会上,看到一些厂家的展示台上,各种船舶.公路.车辆的高清视频直播,好奇这些数据是怎么接到现场的,现场成百上千家展台,不可能有那么大的带宽供应,细想数据肯定不是实时的,果然,盯着看了 ...

  4. vs2015编译EasyDarwin开源流媒体服务器Linux版本调研

    本文转自EasyDarwin团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/51843196 之前InfoQ的一篇文章提到用vs ...

  5. JS中正则匹配开头不带空格,结尾也不带空格的字符串

    在做项目的时候,要求限制SSID的长度.以及开头和结尾不能是空格. var reg = /^\S.{0,30}\S$/ "$$$  $$".match(reg);   ==> ...

  6. Machine Learning in Action(6) AdaBoost算法

    Adaboost也是一种原理简单,但很实用的有监督机器学习算法,它是daptive boosting的简称.说到boosting算法,就不得提一提bagging算法,他们两个都是把一些弱分类器组合起来 ...

  7. json Gson

    package com.example.volleylearn; import java.util.ArrayList; import java.util.List; import java.util ...

  8. Struts页面跳转问题

    只有在web-INF中的jsp才可以不用加namespace名 <s:a action="systemIndexAction_turn" >跳转</s:a> ...

  9. PAT天梯赛 L2-027. 名人堂与代金券 【排序】

    题目链接 https://www.patest.cn/contests/gplt/L2-027 思路 在输入的时候 判断分数 是否符合领取代金券条件 如果符合 SUM 就加上对应的代金券价值 然后在对 ...

  10. 《编程之美》之如何控制CPU的暂用率固定在50%

    <编程之美>第一章 让CPU暂用率听你指挥的粗糙实现,如何控制CPU的暂用率固定在50% #include <stdio.h> #include <Windows.h&g ...