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

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

由此我将引入和介绍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,代码类似于如下的方式:

  1. var xhr = new XMLHttpRequest();
  2. xhr.open("GET", "/hfahe", true);
  3. xhr.send();

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

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

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

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

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

  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. } else if (typeof!= "undefined") {
  9. // 否则检查是否支持XDomainRequest,IE8和IE9支持
  10. // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式
  11. xhr = new XDomainRequest();
  12. xhr.open(method, url);
  13. } else {
  14. // 否则,浏览器不支持CORS
  15. xhr = null;
  16. }
  17. return xhr;
  18. }
  19. var xhr = createCORSRequest('GET', url);
  20. if (!xhr) {
  21. throw new Error('CORS not supported');
  22. }

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

错误显示的很明显,这是因为我们还未设置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>的配置里加入以下内容即可:

  1. Header set Access-Control-Allow-Origin *

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

  1. <?php
  2. header("Access-Control-Allow-Origin:*");

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

  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,都将采用这种统一的解决方案,因为它简单、高效,受到所有主流浏览器的支持。它非常重要,也会让我们的网络变得更加开放。

CORS(跨域资源共享)简介的更多相关文章

  1. CORS跨域资源共享

    CORS(跨域资源共享)跨域问题及解决 当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Co ...

  2. CORS跨域资源共享你该知道的事儿

    "唠嗑之前,一些客套话" CORS跨域资源共享,这个话题大家一定不陌生了,吃久了大转转公众号的深度技术好文,也该吃点儿小米粥溜溜胃里的缝儿了,今天咱们就再好好屡屡CORS跨域资源共 ...

  3. 在ASP.NET Web API中实现CORS(跨域资源共享)

    默认情况下,是不允许网页从不同的域访问服务器资源的,访问遵循"同源"策略的原则. 会遇到如下的报错: XMLHttpRequest cannot load http://local ...

  4. django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享

    一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...

  5. 跨域漏洞丨JSONP和CORS跨域资源共享

    进入正文之前,我们先来解决个小问题,什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 跨域常见的两种方式,分别是JSONP和CORS. 今天i ...

  6. 浅谈跨域问题,CORS跨域资源共享

    1,何为跨域? 在理解跨域问题之前,你先要了解同源策略和URL,简单叙述: 1)同源策略 三同:协议相同,域名相同,端口相同: 目的:保证用户信息安全,防止恶意网站窃取数据.同源策略是必须的,否则co ...

  7. CORS(跨域资源共享)详解及与JSONP的对比

    上篇讲解的JSONP的跨域请求方式,但是在浏览器的支持及请求方式上有局限性,接下来将介绍一种新的跨域请求方式CORS. CORS是一个W3C标准,全称是"跨域资源共享"(Cross ...

  8. Node.js实现CORS跨域资源共享

    什么是CORS CORS(Cross-origin resource sharing),跨域资源共享,是一份浏览器技术的规范,用来避开浏览器的同源策略 简单来说就是解决跨域问题的除了jsonp外的另一 ...

  9. tomcat7.0配置CORS(跨域资源共享)

    平时我们做前台页面时可能会遇到浏览器以下提示(浏览器控制台): 已阻止跨源请求:同源策略禁止读取位于 http://xxx.xxx.com 的远程资源.(原因:CORS 头缺少 'Access-Con ...

  10. CORS跨域资源共享简述

    什么是CORS? 默认情况下,为预防某些而已行为,浏览器的XHR对象只能访问来源于同一个域中的资源.但是我们在日常实际开发中,常常会遇到跨域请求的需求,因此就出现了一种跨域请求的方案:CORS(Cro ...

随机推荐

  1. Java -- String、StringBuffer、StringBuilder

    原文:http://blog.csdn.net/kingzone_2008/article/details/9220691 String:不可变. StringBuffer(JDK1.0):可变,线程 ...

  2. PHP中array_merge和array相加的区别分析

    今天处理一个这样的问题:如何获取字符键名相同值不同的两个数组值集合,用array_merge和数组相加都不可行,让我认真比较了下PHP中array_merge和array相加的区别 首先来看看键名是s ...

  3. JS手机浏览器判断(转)

    整理查询一下,js判断手机浏览器的方法 <script type="text/javascript"> /* * 智能机浏览器版本信息:包括微信内置 * */ var ...

  4. makefile基础(GNU)

    makefile的核心 targets : prerequisites ; commands...   //不分行的情况 targets : prerequisites                 ...

  5. HDU1294 Rooted Trees Problem(整数划分 组合数学 DP)

    讲解见http://www.cnblogs.com/IMGavin/p/5621370.html, 4 可重组合 dfs枚举子树的节点个数,相乘再累加  1 #include<iostream& ...

  6. Java获取当前时间年月日、时间格式化打印、字符串转日期

    package com.sysc.simple; import java.text.ParseException; import java.text.SimpleDateFormat; import ...

  7. socket编程学习

    socket: 也称作套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求. 常用的套接字API函数: 1.socket(): 函数原型为:int socket(int domain, int ...

  8. RDS MySQL 全文检索相关问题的处理

    RDS MySQL 全文检索相关问题 1. RDS MySQL 对全文检索的支持 2. RDS MySQL 全文检索相关参数 3. RDS MySQL 全文检索中文支持 3.1 MyISAM 引擎表 ...

  9. IM服务器的架构

    一. 总的构架结构示意图: 如上图所示,目前系统总的分成六个模块, 分别为网络/协议解析模块,用户帐号管理模块,消息处理模块,动作处理模块,数据均衡处理模块,客户状态处理模块 . 正常流程应该这么实现 ...

  10. Java可变参数讲解

    如果实现的多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数的个数,可以使用可变参数可变参数的定义方法 数据类型...数组的名称,这个数组存储传递过来的参数,类似JavaScript注意点:  ...