浙江省sxcors网站应用指南是什么

本篇包括以下内容:
CORS 对比 JSONP
CORS,BROWSER支持情况
Ajax请求跨域资源的异常
CORS 实现思路
CORS 几种解决方案
自定义CORSFilter
Nginx 配置支持Ajax跨域
支持多域名配置的CORS Filter
keyword:cors,跨域,ajax,403,filter,RESTful,origin,http,nginx,jsonp
原创作品,转载请附带原文路径:
Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。
CORS是W3c工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。
同源策略:是浏览器最核心也最基本的安全功能;同源指的是:同协议,同域名和同端口。精髓:认为自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源;
JSON & JSONP:JSON 是一种基于文本的数据交换方式,或者叫做数据描述格式。JSONP是资料格式JSON的一种“使用模式”,可以让网页从别的网域要资料,由于同源策略,一般来说位于的网页无法与不是 的服务器沟通,而HTML的script元素是一个例外。利用script元素的这个开放策略,网页可以得到从其他来源动态产生的JSON资料,而这种使用模式就是所谓的JSONP
CORS 对比 JSONP
都能解决 Ajax直接请求普通文件存在跨域无权限访问的问题
JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求
使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理
JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS
CORS,BROWSER支持情况
数据来源:
IE6,IE7,Opera min 不支持CORS。具体可参看数据来源中的 'show all'
From a browser script perspective: By allowing cross-domain requests, which are subject to tighter controls on the types of data that is exchanged. Cookies, for instance, are blocked unless specifically requested by the XHR author and allowed by the cross-domain web service. This is done to mitigate the risk of data leaks.
From a web service perspective: By utilising the origin URL reported by the browser the target cross-domain web service can determine, based on its origin policy, whether to allow or deny the request.
Ajax请求跨域资源的异常
当出现如下异常时,那么就需要考虑跨域的问题了
例如 localhost:63343 通过Ajax请求http://192.168.10.61:8080服务器资源时就会出现如下异常:
CORS 实现思路
CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否
CORS is not about providing server-side security. The Origin request header is produced by the browser and the server has no direct means to verify it.
CORS 并不是为了解决服务端安全问题,而是为了解决如何跨域调用资源。至于如何设计出 安全的开放API,却是另一个问题了,这里提下一些思路:
请求时间有效性(验证timestamp与服务接到请求的时间相差是否在指定范围内,比如5分钟内)
'name': 用户名,
‘key: 加密的验证key,//(name+secret+timestamp来通过不可逆加密生成)
‘timestamp’: 时间戳,//验证timestamp与服务接到请求的时间相差是否在指定范围内,比如5分钟内
CORS 几种解决方案
CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否.
Access-Control-Allow-Origin:指定授权访问的域
Access-Control-Allow-Methods:授权请求的方法(GET, POST, PUT, DELETE,OPTIONS等)
一:简单的自定义CORSFilter / Interceptor
适合设置单一的(或全部)授权访问域,所有配置都是固定的,特简单。也没根据请求的类型做不同的处理
在web.xml 中添加filter
&filter-name&cros&/filter-name&
&filter-class&cn.ifengkou.test.filter.CORSFilter&/filter-class&
&filter-mapping&
&filter-name&cros&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
新增CORSFilter 类
@Component
public class CORSFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader(&Access-Control-Allow-Origin&, &*&);
response.addHeader(&Access-Control-Allow-Methods&, &GET, POST, PUT, DELETE&);
response.addHeader(&Access-Control-Allow-Headers&, &Content-Type&);
response.addHeader(&Access-Control-Max-Age&, &1800&);//30 min
filterChain.doFilter(request, response);
Access-Control-Allow-Origin只能配置
或者一个域名*
比如配置了192.168.56.130,那么只有192.168.56.130 能拿到数据,否则全部报403异常
response.addHeader(&Access-Control-Allow-Origin&, &http://192.168.56.130&);
二:Nginx 配置支持Ajax跨域
这里是一个nginx启用COSR的参考配置:
# Wide-open CORS config for nginx
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# Custom headers and headers various browsers *should* be OK with but aren't
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
三:支持多域名配置的CORS Filter
因为知道已经有可以用的库可以解决,所以就没重复造轮子了。其实因为懒,看看别人的源码算了。。。
在搜索cors-filter,目前也就两个可以用
org.ebaysf.web 的 cors-filter,项目地址:
com.thetransactioncompany的 cors-filter,项目地址:
这两个也都大同小异,因为ebay开源在github上,也有详细的README,那么就以ebay的cors-filter为例
添加依赖包到项目:
&dependency&
&groupId&org.ebaysf.web&/groupId&
&artifactId&cors-filter&/artifactId&
&version&1.0.1&/version&
&/dependency&
添加配置(具体配置项,还是见项目的吧)
&filter-name&CORS Filter&/filter-name&
&filter-class&org.ebaysf.web.cors.CORSFilter&/filter-class&
&init-param&
&param-name&cors.allowed.origins&/param-name&
&param-value&http://192.168.56.129,http://192.168.56.130&/param-value&
&/init-param&
&init-param&
&param-name&cors.allowed.methods&/param-name&
&param-value&GET,POST,HEAD,OPTIONS,PUT&/param-value&
&/init-param&
&init-param&
&param-name&cors.allowed.headers&/param-name&
&param-value&Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers&/param-value&
&/init-param&
&filter-mapping&
&filter-name&CORS Filter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
源码地址:。但通过IDEA Decompiled 出来的更清晰.....,以下是反编译的
ebaysf的cors-filter 只有一个类CORSFilter。也就是一个拦截器,implements Filter
public final class CORSFilter implements Filter {
通过是实现Filter 的init 方法从配置文件中读取参数:
public void init(FilterConfig filterConfig) throws ServletException {
this.parseAndStore(&*&, &GET,POST,HEAD,OPTIONS&, &Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers&, &&, &true&, &1800&, &false&, &true&);
this.filterConfig = filterC
this.loggingEnabled =
if(filterConfig != null) {
String configAllowedOrigins = filterConfig.getInitParameter(&cors.allowed.origins&);
String configAllowedHttpMethods = filterConfig.getInitParameter(&cors.allowed.methods&);
String configAllowedHttpHeaders = filterConfig.getInitParameter(&cors.allowed.headers&);
String configExposedHeaders = filterConfig.getInitParameter(&cors.exposed.headers&);
String configSupportsCredentials = filterConfig.getInitParameter(&cors.support.credentials&);
String configPreflightMaxAge = filterConfig.getInitParameter(&cors.preflight.maxage&);
String configLoggingEnabled = filterConfig.getInitParameter(&cors.logging.enabled&);
String configDecorateRequest = filterConfig.getInitParameter(&cors.request.decorate&);
this.parseAndStore(configAllowedOrigins, configAllowedHttpMethods, configAllowedHttpHeaders, configExposedHeaders, configSupportsCredentials, configPreflightMaxAge, configLoggingEnabled, configDecorateRequest);
parseAndStore 方法,解析参数。以 解析cors.allowed.orgins为例;其他参数同理
if(allowedOrigins != null) {
if(allowedOrigins.trim().equals(&*&)) {
this.anyOriginAllowed =
this.anyOriginAllowed =
e = this.parseStringToSet(allowedOrigins);
this.allowedOrigins.clear();
this.allowedOrigins.addAll(e);
//parseStringToSet
//对多域名用点分割,加到HashSet中,再赋给allowedOrigins(Collection&String& allowedOrigins = new HashSet();)
private Set&String& parseStringToSet(String data) {
if(data != null && data.length() & 0) {
splits = data.split(&,&);
splits = new String[0];
HashSet set = new HashSet();
if(splits.length & 0) {
String[] arr$ =
int len$ = splits.
for(int i$ = 0; i$ & len$; ++i$) {
String split = arr$[i$];
set.add(split.trim());
如何实现 doFilter
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if(servletRequest instanceof HttpServletRequest && servletResponse instanceof HttpServletResponse) {
HttpServletRequest request1 = (HttpServletRequest)servletR
HttpServletResponse response = (HttpServletResponse)servletR
//识别request 属于哪种类别
CORSFilter.CORSRequestType requestType = this.checkRequestType(request1);
if(this.decorateRequest) {
decorateCORSProperties(request1, requestType);
switch(CORSFilter.SyntheticClass_1.$SwitchMap$org$ebaysf$web$cors$CORSFilter$CORSRequestType[requestType.ordinal()]) {
this.handleSimpleCORS(request1, response, filterChain);
this.handleSimpleCORS(request1, response, filterChain);
this.handlePreflightCORS(request1, response, filterChain);
this.handleNonCORS(request1, response, filterChain);
this.handleInvalidCORS(request1, response, filterChain);
String request = &CORS doesn\'t support non-HTTP request or response.&;
throw new ServletException(request);
判断request类别,根据类别进行差异化处理。handleSimpleCORS 处理过程,判断是否设置允许所有origin参数,判断是否符合httpMethods要求,判断此次request的origin(origin = request.getHeader(&Origin&))是否在allowedOrigins(origin白名单)内。如果在,就设置response.addHeader(&Access-Control-Allow-Origin&, origin);这样也就实现了多域名支持。流程图就不画了...
public void handleSimpleCORS(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
CORSFilter.CORSRequestType requestType = this.checkRequestType(request);
if(requestType != CORSFilter.CORSRequestType.SIMPLE && requestType != CORSFilter.CORSRequestType.ACTUAL) {
origin = &Expects a HttpServletRequest object of type & + CORSFilter.CORSRequestType.SIMPLE + & or & + CORSFilter.CORSRequestType.ACTUAL;
throw new IllegalArgumentException(origin);
origin = request.getHeader(&Origin&);
String method = request.getMethod();
if(!this.isOriginAllowed(origin)) {
this.handleInvalidCORS(request, response, filterChain);
} else if(!this.allowedHttpMethods.contains(method)) {
this.handleInvalidCORS(request, response, filterChain);
if(this.anyOriginAllowed && !this.supportsCredentials) {
response.addHeader(&Access-Control-Allow-Origin&, &*&);
response.addHeader(&Access-Control-Allow-Origin&, origin);
if(this.supportsCredentials) {
response.addHeader(&Access-Control-Allow-Credentials&, &true&);
if(this.exposedHeaders != null && this.exposedHeaders.size() & 0) {
String exposedHeadersString = join(this.exposedHeaders, &,&);
response.addHeader(&Access-Control-Expose-Headers&, exposedHeadersString);
filterChain.doFilter(request, response);
为了避免对参数一知半解,就把作者的参数描述表贴上来,通过参数表可以了解下header里面各个参数的作用
cors.allowed.origins
A list of origins that are allowed to access the resource. A '' can be specified to enable access to resource from any origin. Otherwise, a whitelist of comma separated origins can be provided. Ex: , . Defaults:
(Any origin is allowed to access the resource).
cors.allowed.methods
A comma separated list of HTTP methods that can be used to access the resource, using cross-origin requests. These are the methods which will also be included as part of 'Access-Control-Allow-Methods' header in a pre-flight response. Ex: GET,POST. Defaults: GET,POST,HEAD,OPTIONS
cors.allowed.headers
A comma separated list of request headers that can be used when making an actual request. These header will also be returned as part of 'Access-Control-Allow-Headers' header in a pre-flight response. Ex: Origin,Accept. Defaults: Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers
cors.exposed.headers
A comma separated list of headers other than the simple response headers that browsers are allowed to access. These are the headers which will also be included as part of 'Access-Control-Expose-Headers' header in the pre-flight response. Ex: X-CUSTOM-HEADER-PING,X-CUSTOM-HEADER-PONG. Default: None
cors.preflight.maxage
The amount of seconds, browser is allowed to cache the result of the pre-flight request. This will be included as part of 'Access-Control-Max-Age' header in the pre-flight response. A negative value will prevent CORS Filter from adding this response header from pre-flight response. Defaults: 1800
cors.support.credentials
A flag that indicates whether the resource supports user credentials. This flag is exposed as part of 'Access-Control-Allow-Credentials' header in a pre-flight response. It helps browser determine whether or not an actual request can be made using credentials. Defaults: true
cors.logging.enabled
A flag to control logging to container logs. Defaults: false
cors.request.decorate
A flag to control if the request should be decorated or not. Defaults: true
1.服务端准备接口(我的地址是:)
@RequestMapping(method = RequestMethod.GET,value = &test&)
@ResponseBody
public HashMap&String,Object& getArticles(){
HashMap&String,Object& map = new HashMap&&();
map.put(&result&,&success&);
2.过滤器配置(web.xml),配置允许访问的域为:
&filter-name&CORS Filter&/filter-name&
&filter-class&org.ebaysf.web.cors.CORSFilter&/filter-class&
&init-param&
&param-name&cors.allowed.origins&/param-name&
&param-value&http://192.168.56.129,&/param-value&
&/init-param&
&filter-mapping&
&filter-name&CORS Filter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
3.准备测试网页index.html:
&!DOCTYPE html&
&html lang=&en&&
&meta charset=&UTF-8&&
&title&cors test page&/title&
&script src=&jquery.min.js&&&/script&
function loadData(){
url: &http://192.168.10.61:8080/api&,
type:&GET&,
dataType:&json&,
timeout:10000,
success:function(data){
$(&#result&).append(data.result+&&br /&&);
console.log(data);
error:function(e){
$(&#result&).append(e.statusText+&&br /&&);
$(function(){
$(&#host&).append(&origin:&+window.location.origin);
&button onclick=&loadData()&&onclick&/button&
&div id=&host&&&/div&
&div id=&result& style=&height:200width:100%&&&/div&
4.将index.html发布到nginx(nginx后面也有方案)
index.html 不能直接用浏览器打开运行,虽然可以调用Ajax请求,但是域是file:///path/index.html
虚拟机增加一个网卡地址(原机器IP是192.168.56.129)
ifconfig eth0:0 192.168.56.130
建立两个测试网站
mkdir /website1 #站点目录
mkdir /website2
将index.html 传输到这两个目录
配置nginx,增加两个server节点
# ----server1 ----
192.168.56.129:80;
location / {
/website1;
index.html index.
# ----server2 ----
192.168.56.130:80;
location / {
/website2;
index.html index.
重启nginx服务
./nginx -s reload
5.修改本地hosts文件
//hosts文件路径:windows系统一般在C:\Windows\System32\drivers\etc
192.168.56.129
192.168.56.130
通过增加虚拟网卡 、nginx代理 和 修改hosts文件,我在本地就有4个网站(域)可以进行测试了,分别是:
(chrome)打开4个tab,分别进入到上述四个网站,页面打印了当前origin,通过onclick调用Ajax请求,页面布局如下
符合预期!
建议使用,除了对域的过滤,还做了其他很多操作,比简单的自定义过滤器考虑得周全,例如
this.handlePreflightCORS(request1, response, filterChain);
this.handleNonCORS(request1, response, filterChain);
this.handleInvalidCORS(request1, response, filterChain);
cors在开发WebService、RESTful API 时经常会遇到,在以前可能直接通过jsonp解决,jsonp怎样怎样就不多说了。 总之,CORS技术规范出来这么久了,如果不考虑IE6 IE7的问题,那么还是积极拥抱CORS吧
上文三种解决方案,通过搜索引擎均能找到,但估计大部分都是用的第一种最简单的无脑的Cors Filter处理,第二种方案是通过nginx配置的,并不适合所有Web应用。第三种,考虑得很周全,而且使用方便,如果不考虑造重复轮子,推荐使用。
本文所用的测试工程代码太简单了,就不放github了,直接下载吧,
断断续续写了好几天,转载请附带原文路径:
阅读(...) 评论()是否能限制跨域(CORS)访问的来源?只授权给特定的网站. - 知乎5被浏览410分享邀请回答b.com")即可0添加评论分享收藏感谢收起CORS测量技术在浙江省沿海重点区域海洋灾害风险评估中的应用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
CORS测量技术在浙江省沿海重点区域海洋灾害风险评估中的应用
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢&&&&&&&&&&&&&&&&&&
posts - 81,comments - 37,trackbacks - 0
本文为译文。
&&& APIS是可以将富网页应用串连在一起的线程。但是这个应用难以转给浏览器,跨域请求技术的选择被限制了,类似JSONP(由于安全考虑,使用会被限制),或者配置代理(设置和维护都比较头痛)。
&&& Cross-Origin Resource Sharing(CORS)是允许来自浏览器的跨域通信的W3C规范。通过设置XMLHttpRequest的头部,CORS允许开发者使用类似同域中请求惯用的方法。
&&& CORS的用法很简单,假设网站有一些想要获取的数据。这类型的请求以前通常在浏览器的同源策略下不被允许。但是,借助CORS请求,可以加一些特殊回应头信息允许取得数据。
&&& 可以从这个例子里面看出来,支持CORS需要服务器和客户端之间的协调。幸运的是,如果你是客户端开发者,你可以屏蔽掉这中间大多数的细节。这篇文章余下的部分会展示客户端如何进行跨域请求,及服务器如何配置来支持CORS。
发起CORS请求
&&& 这部分介绍如何使用javascript发起CORS请求。
&&& 创建XMLHttpRequest请求:
&&& 下列浏览器支持CORS:
&&& Chrome 3+
&&& Firefox 3.5+
&&& Opera 12+
&&& Safari 4+
&&& Internet Explorer 8+
&&& Chrome,Firefox,Opera,Safari都使用XMLHttpRequest2对象,IE使用类似的XDomainRequest对象,与他本身对应的XMLHttpRequest对象工作机制基本相同,但是另外增加了安全防范。
&&& 首先要创建合适的请求对象,像这样:
&&& 原始的XMLHttpRequest只有一个事件处理onreadystatechange,来处理所有的响应。虽然onreadystatechange依然可以使用,XMLHttpRequest2引进了一系列新的处理,下面是一个列表:
&&& 在大多数情况下,你只仅仅想处理onload和onerror事件:
&&& 当有错误的时候,浏览器不会报告是什么错误。例如,FF对所有错误报告一个状态0和空statusText。浏览器也会向控制输出台报错,但是这个消息没法被javascript获取到。当处理onerror的时候,会知道有一个错误发生了,但没有更多信息了。
withCredentials
&&& 标准的CORS在默认情况下不发送和设置任何cookie。为了使cookie成为请求的一部分包含进来,需要设置XMLHttpRequest的withCredentials属性为true:
&&& 为了达成这个目的,服务器也需要设置Access-Control-Allow-Credientials为true来允许认证。
&&& withCredentials属性会包含来自远程域的请求的任何cookie。注意这些cookies仍然遵循同源策略,所以你的javascript代码仍然从document.cookie中访问不到这些cookies或者请求头.他们只能被远程域所控制。
&&& 现在你的CORS请求已经配置好了,你准备发送请求。这个通过调用send()方法来实现:
&&& 如果请求包含请求体,可以被指定为一个参数给send().
&&& 就是酱紫!假定服务器已经完全配置好来响应CORS请求了,你的onload处理会收到响应,就像你十分熟悉的标准的同域XHR那样。
最后最后一个例子
&&& 这是一个完整的CORS请求例子。运行下例子在浏览器debugger里面看看发送的请求。
在服务器端添加CORS支持
&&& 多数的CORS重担在浏览器和服务器之间被处理了。浏览器增加了额外的一些头,有时发起额外的请求,在CORS请求期间。这些额外的请求对于客户端是不可见的(可以使用Wireshark等工具来捕获)。
&&& 浏览器厂商对于浏览器端的实现是有责任的。下面了解下服务器端如何配置来支持CORS。
请求的类型
跨域请求分类:
&&& 1.简单请求
&&& 2.非简单请求
&&& 简单请求不需要使用CORS从浏览器发出请求。例如,一个JSONP跨域请求可以是一个跨域的GET请求。
&&& 非简单请求,在浏览器与服务器间需要一点额外的交互。
处理一个简单请求
&&& 以一个客户端的简单请求为例。下面代码展示了javascript的一个GET请求,以及浏览器发送的实际请求。CORS中特殊的头粗体显示。
&&& 首先需要注意的是,一个合法的CORS请求总是包含Origin头。这个Origin头是浏览器加上去的,并且不能被用户控制。这个头的值是来自请求源的协议(例如http),域(例如),和端口(只在不是默认端口的情况下包含,例如81);例如.
&&& Origin头的存在不意味着请求是一个跨域请求。虽然所有跨域的请求都会包含Origin头,一些同域请求同样也会包含Origin头。例如,火狐在同域请求中不包含Origin头。但是Chrome和Safari在同域的POST/PUT/DELETE请求(同域的GET请求不会有Origin头)中会包含Origin头。下面有一个同域请求包含Origin头的例子:
&&& 值得庆幸的是浏览器在同域请求时不会期望CORS请求头。同域请求的响应发送给用户,不管是否有CORS请求头。然而,如果服务器代码返回了如果Origin不匹配允许的域列表的错误,确保包含请求的来源域。
&&& 所有CORS相关的的头都是Access-Control为前缀的。下面是每个头的一些细节。
&&& Access-Control-Allow-Origin(必须)-这个头在所有合法的CORS响应中必须被包含;发送头会引起CORS请求失败。这个头的值可以是Origin请求头的回应(就像上面的例子里面一样),或者是允许来自任何域请求的"*"。如果你希望任何站点都可以获取数据,使用"*"就很好。但是如果你希望更好的控制谁可以获取你的数据,在头中使用一个实际的值。
&&& Access-Control-Allow-Credentials(可选)-默认情况下,cookies在CORS请求中不被包含。使用这个头意味着在CORS请求中应当包含cookies.这个头的唯一合法值是true(全部小写)。如果不需要cookies,不要包含这个头(而不是把值设置为false).
&&& Access-Control-Allow-Credentials头与XMLHttpRequest2的withCredentials属性结合使用。所有这些属性都必须设置为true以便于CORS请求能够成功。如果withCredentials是true,但是没有Access-Control-Allow-Credentials头,请求会失败(反之亦然)。
&&& 上面提到过,除非你确定需要cookies包含在请求中,否则不设置这个头。
&&& Access-Control-Expose-Headers(可选)-XMLHttpRequest2对象有一个返回特别响应头值的getResponseHeader()方法。在CORS请求中,getResponseHeader()只能获取简单的响应头。简单响应头定义如下:
&&& 如果希望客户端获取其他头,必须用Access-Control-Expose-Headers头。这个头的值是一个逗号分隔的想要公开给客户端的响应头列表。
处理非简单请求
&&& 上面就是如何处理简单GET请求,但如果想要做更多的事情要怎么做?也许你想要支持其他HTTP动作,像PUT或DELETE,或者想要使用Content-Type:application/json支持JSON.你就需要处理所谓非简单请求。
&&& 非简单请求看上去像到客户端的一个单一请求,但是实际上在遮罩下包含了两个请求。浏览器首先发出一个预先请求,就好像询问服务器应允进行实际请求。一旦被允许,浏览器发送实际请求。浏览器透明的处理这两个请求的细节。预响应也可以被缓存下来以便不需要在每个请求前都发送。
&&& 下面是一个非简单请求的例子:
&&& 像简单请求一样,浏览器给每个请求加上Origin头,包含预请求。预请求像HTTP OPTIONS请求一样发出(所以确保服务器可以响应这个方法).他也包含额外的一些头:
&&&&&Access-Control-Request-Method-HTTP实际请求的方法。这个请求头总是被包含,即使HTTP请求是一个简单请求,就像早些定义的那些(GET,POST,HEAD).
&&&& Access-Control-Request-Headers-一个在请求中包含的非简单头的逗号分隔的列表。
&&& 预请求是在发送实际请求前,问询服务器是否允许实际请求的方式。服务器应当检查上面的两个头来确认HTTP方法和请求头是合法的及可以接受的。
&&& 如果HTTP请求方法和头是合法的,服务器会如下响应:
&&& Access-Control-Allow-Origin(必须)-如简单响应一样,预响应必须包含这个头。
&&& Access-Control-Allow-Method(必须)-所支持的HTTP方法逗号分隔的列表。注意虽然预请求只是询问HTTP方法是否允许,响应头可以包含所有支持的HTTP方法。这个是有帮助的,因为预响应可能会被缓存,所以单一的预响应可以包含多种请求类型的细节。
&&& Access-Control-Allow-Headers(如果请求头包含Access-Control-Allow-Headers就必须包含)-逗号分隔的所支持的请求头列表。像上面的Access-Control-Allow-Methods一样,这个可以列出服务器支持的所有头(不仅仅是在预请求中请求的头)。
&&& Access-Control-Allow-Credentials(可选)-同简单请求。
&&& Access-Control-Max-Age(可选)-在每个请求上进行预请求是代价很高的,因为浏览器对于客户端的请求会进行两次请求。这个头的值允许预响应缓存一个指定的秒数。
&&& 一旦预请求给到了应允,浏览器发送实际请求。实际请求看起来像简单请求,响应以同样的方式处理:
&&& 如果服务器想否决CORS请求,可以只返回一个通用的响应(像HTTP 200),不带任何CORS请求头。如果预请求时的HTTP方法或者头不合法,服务器可能想要否决请求。由于在响应中没有CORS特定的头,浏览器断定请求是不合法的,不发送实际请求:
&&& 如果在CORS请求中有错误,浏览器会触发客户端的onerror事件处理。也会在控制台上打印下面的错误:
&&& 浏览器不会给为什么错误会发生的细节信息,只告诉你出了些问题。
&&& 虽然CORS奠定了跨域请求的基础工作,CORS头不是健全的安全实践的替代。在站点上不能够依赖CORS头保护资源安全。使用CORS头给予浏览器跨域请求的接入,但是使用其他的安全手段,像cookies或者OAuth2,如果需要额外的安全限制的话。
来自jQuery的CORS
&&& jQuery的$.ajax()方法可以用来进行常规XHR请求和CORS请求。一点点jQuery相关实现的笔记:
&jQuery的CORS实现不包含IE的XDomainRequest对象。但是有jQuery插件可以用这个。可以在上查看细节。
&如果浏览器支持CORS的话(在IE中会返回false,看下上条说明),$.support.cors布尔量会被设置成true。这是检查是否支持CORS的快速方法。
&&& 下面是一个用jQuery进行CORS请求的例子。注释给出了确切的属性如何与CORS交互。
Chrome扩展件的跨域
&&& Chrome扩展件以两种不同的方式支持跨域:
在manifest.json中包含域-Chrome扩展件可以向任何域发送跨域请求,如果域被包含在manifest.json文件的permissions部分:服务器不需要包含任何额外的CORS头或者做另外的工作来使请求成功。
CORS请求-如果域不在manifest.json文件中,Chrome扩展件进行一个标准的CORS请求。Origin头的值是"chrome-extension://[CHROME EXTENSION ID]".这意味着来自Chrome扩展件的请求受本文提到的同样的CORS请求规则的约束。
CORS w/图片
&&& 在Canvas和WebGL上下文中,跨域图片可以造成很大的问题。可以在img元素上使用crossOrigin属性。
CORS服务器流程图
&&& 下面的流程图说明了服务器如何确定在CORS响应中需要加哪些头。
相关文章:
阅读(...) 评论()

我要回帖

更多关于 corsfilter 的文章

 

随机推荐