文档章节

HTML5安全:CORS(跨域资源共享)简介

mac_zhao
 mac_zhao
发布于 2014/10/02 17:48
字数 1607
阅读 255
收藏 23

前言:像CORS对于现代前端这么重要的技术在国内基本上居然很少有人使用和提及,在百度或者Google上搜索CORS,搜到的中文文章基本都是另外一种卫星定位技术CORS的介绍,让我等前端同学情何以堪(对比起来,用Google搜到的国外文章,基本都是跨域资源共享的介绍,说明了前端技术在国内外环境和发展的巨大差距)。

        我之前《用HTML5实现人脸识别》这篇文章中提到了“Face.com实现了CORS(跨域资源共享)。CORS系统基本上可以让服务器暴露给其它域上文件的Ajax调用。这是一个伟大的功能,我希望更多的服务能够使用它。”在这篇文章介绍的实现方式里,我们可以自由的使用自己本域的JS代码通过Ajax来调用Face.comAPI,这是一种很美妙的方式,而在以前我们很难做到这一点。

        由此我将引入和介绍CORS,希望对大家有所帮助。

定义

        CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。

        而W3C的官方文档目前还是工作草案,但是正在朝着W3C推荐的方向前进。

        简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。

以往的解决方案

        以前要实现跨域访问,可以通过JSONP、Flash或者服务器中转的方式来实现,但是现在我们有了CORS。

        CORS与JSONP相比,无疑更为先进、方便和可靠。

        1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

        2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

        3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS(这部分会在后文浏览器支持部分介绍)。

详细内容

        要使用CORS,我们需要了解前端和服务器端的使用方法。

        1、  前端

        以前我们使用Ajax,代码类似于如下的方式:

[html]  view plain copy
  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "/hfahe", true);  
  3. xhr.send();  

        这里的“/hfahe”是本域的相对路径。

        如果我们要使用CORS,相关Ajax代码可能如下所示:

[html]  view plain copy
  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "http://blog.csdn.net/hfahe", true);  
  3. xhr.send();  

        请注意,代码与之前的区别就在于相对路径换成了其他域的绝对路径,也就是你要跨域访问的接口地址。

        我们还必须提供浏览器回退功能检测和支持,避免浏览器不支持的情况。



  
  
  
  

  

  

   
   
[html] view plain copy
  1. function createCORSRequest(method, url) {  
  2.   var xhr = new XMLHttpRequest();  
  3.   if ("withCredentials" in xhr) {  
  4.     // 此时即支持CORS的情况  
  5.     // 检查XMLHttpRequest对象是否有“withCredentials”属性  
  6.     // “withCredentials”仅存在于XMLHTTPRequest2对象里  
  7.     xhr.open(method, url, true);  
  8.    
  9.   } else if (typeof!= "undefined") {  
  10.    
  11.     // 否则检查是否支持XDomainRequest,IE8和IE9支持  
  12.     // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式  
  13.     xhr = new XDomainRequest();  
  14.     xhr.open(method, url);  
  15.    
  16.   } else {  
  17.    
  18.     // 否则,浏览器不支持CORS  
  19.     xhr = null;  
  20.    
  21.   }  
  22.   return xhr;  
  23. }  
  24.    
  25. var xhr = createCORSRequest('GET', url);  
  26. if (!xhr) {  
  27.   throw new Error('CORS not supported');  
  28. }  

        现在如果直接使用上面的脚本进行请求,会看到浏览器里控制台的报错如下:

        错误显示的很明显,这是因为我们还未设置Access-Control-Allow-Origin头。

        2、  服务器

        服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

        HTTP 头的设置方法有很多,http://enable-cors.org/这篇文章里对各种服务器和语言的设置都有详细的介绍,下面我们主要介绍Apache和PHP里的设置方法。

        Apache:Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可:

[html]  view plain copy
  1. Header set Access-Control-Allow-Origin *  

        PHP:只需要使用如下的代码设置即可。

[html]  view plain copy
  1. <?php  
  2.  header("Access-Control-Allow-Origin:*");  

        以上的配置的含义是允许任何域发起的请求都可以获取当前服务器的数据。当然,这样有很大的危险性,恶意站点可能通过XSS攻击我们的服务器。所以我们应该尽量有针对性的对限制安全的来源,例如下面的设置使得只有http://blog.csdn.net这个域才能跨域访问服务器的API。

[html]  view plain copy
  1. Access-Control-Allow-Origin: http://blog.csdn.net  

浏览器支持情况


        上图为各浏览器对于CORS的支持情况(绿色为支持,数据来源:http://caniuse.com/cors),看起来相当乐观。主流浏览器都已基本提供对跨域资源共享的支持,所以,CORS才会在国外使用的如此普遍。

        上文曾经提到,IE8和IE9在某种程度上可以通过XDomainRequest来提供同样功能的支持。

使用案例

        目前国外支持CORS的平台有很多,例如:

        Google APIClient Library for JS

        Google CloudStorage

        Face.com API

未来

        从所有的浏览器都支持来看,CORS将成为未来跨域访问的标准解决方案。无论是自己服务器间的跨域访问,还是开放平台为第三方提供API,都将采用这种统一的解决方案,因为它简单、高效,受到所有主流浏览器的支持。它非常重要,也会让我们的网络变得更加开放。

参考文章

        IE10中的CORS forXHR

        USING CORS

        原创文章,转载请注明:来自蒋宇捷的博客(http://blog.csdn.net/hfahe)

© 著作权归作者所有

共有 人打赏支持
mac_zhao
粉丝 42
博文 249
码字总数 304671
作品 0
普陀
程序员
私信 提问
加载中

评论(1)

gaubee
gaubee
跨域cookies共享也是个问题
转:XMLHttpRequest2 新技巧

”XMLHttpRequest 的异步调用网上找的例子运行没问题,但稍微改了一点点就报错”InvalidStateError: XMLHttpRequest has an invalid context“。断断续续 搞了3天终于通了,可以接收二进制文...

SamXIAO
09/24
0
0
浏览器同源策略及 Ajax 跨域解决方案

因为在开发过程中会经常遇到因为浏览器同源策略而导致的跨域问题,而多数开发者对浏览器同源策略和跨域问题并没有很清晰的认识,所以打算在这篇文章中说下浏览器同源策略和我们最经常会遇到的...

淘淘笙悦
07/13
0
0
HTML5 WebMessaging 体验

下载演示文件 - 2.97 KB 简介 作为WEB开发者,经常会遇到一个问题: 跨域通信和“同源政策”的协调化。因为 JavaScript 代码不能访问位于不同 域(或子域) 或 协议 (HTTP/HTTPs) 或 端口 的代...

oschina
2014/04/29
619
0
HTML5安全风险详析之一:CORS攻击

CORS-CrossOrigin Resources Sharing,也即跨源资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说...

zyt_1978
2016/03/19
17
0
浏览器同源政策及其规避方法

浏览器安全的基石是"同源政策"(same-origin policy)。很多开发者都知道这一点,但了解得不全面。 本文详细介绍"同源政策"的各个方面,以及如何规避它。 一、概述 1.1 含义 1995年,同源政策...

oschina
2016/04/10
3.7K
7

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 眼看着这个陨石砸了下来

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:分享Nachtblut的单曲《Antik》 《Antik》- Nachtblut 手机党少年们想听歌,请使劲儿戳(这里) @mr_chip :上海的初雪之后有点冷 ...

小小编辑
8分钟前
2
1
Confluence 6 修改导航显示选项

选择 子页面(Child pages)来在边栏中查看当前页面的子页面。 选择 页面树(Page tree)来查看整个空间的页面树,扩展当前的页面。 你也可以选择是否完全隐藏导航显示选项或者添加你希望可见...

honeymose
40分钟前
0
0
Ubuntu18.04 安装MySQL

1.安装MySQL sudo apt-get install mysql-server 2.配置MySQL sudo mysql_secure_installation 3.设置MySQL非root用户 设置原因:配置过程为系统root权限,在构建MySQL连接时出现错误:ERROR...

AI_SKI
今天
3
0
3.6 rc脚本(start方法) 3.7 rc脚本(stop和status方法) 3.8 rc脚本(以daemon方式启动)

3.6-3.7 rc脚本(start、stop和status方法) #!/usr/bin/env python# -*- coding: utf-8 -*-# [@Version](https://my.oschina.net/u/931210) : python 2.7# [@Time](https://my.oschina.......

隐匿的蚂蚁
今天
3
0
Cnn学习相关博客

CNN卷积神经网络原理讲解+图片识别应用(附源码) 笨方法学习CNN图像识别系列 深度学习图像识别项目(中):Keras和卷积神经网络(CNN) 卷积神经网络模型部署到移动设备 使用CNN神经网络进行...

-九天-
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部