什么是CORS?

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

CORS背后的原理是:使用自定的HTTP头部与服务器进行沟通,从而由服务器决定响应是否成功

如何使用CORS?

使用CORS需要客户端和服务端两者配合。

一、客户端如何发起CORS跨域请求?

目前在大多数浏览器下(CORS在各浏览器下支持情况),都原生支持CORS,代码编写时和同域的请求差不多,只需要在xhr.open()的时候传入绝对URL即可。例如:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
console.log(xhr.responseText)
}else {
console.log('err' + xhr.status);
}
}
};
xhr.open('get','http://www.xxx.com/api/something/',true);
xhr.send(null);

这样就可以发送一个跨域请求了,但是如果只是如上面示例代码一样发送的话会报错,因为服务器并未设置允许我们这个请求,因此CORS还需要服务端来配合。

二、服务器如何允许客户的CORS跨域请求?

服务器只需要在响应头部中设置Access-Control-Allow-Origin即可让客户端访问。

假设客户端的域名是http://www.xxx.com,那么服务端只要在Access-Control-Allow-Origin的设置中含有http://www.xxx.com,那么这个CORS请求即可成功。如果Access-Control-Allow-Origin设置为*,那么任意域名都可以访问这个服务端,但是为了安全起见,一般并不建议这样做。

以下截图是一个CORS请求后服务端正常返回的示例:

Preflighted Request

CORS还有一种叫做Preflighted Request(预飞请求)的透明服务器验证机制完成请求过程,如果你在请求的时候使用了表1中的选项来发送请求(使用setRequestheaders设定自定义头部),那么就会触发Preflighted Request,它的请求过程如下:

1.XHR对象send发出请求

2.浏览器先向服务端发出一个OPTIONS方法的请求,并发送下列头部:

  • 表1
请求头部信息 含义
Origin 来源域名,与简单的请求相同。
Access-Control-Request-Method 请求自身使用的方法。
Access-Control-Request-Headers (可选) 自定义的头部信息,多个头部以逗号分隔。

OPTIONS请求示例:

客户端请求的代码(比上面多加了个header):

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
console.log(xhr.responseText)
}else {
console.log('err' + xhr.status);
}
}
};
xhr.open('get','http://www.xxx.com/api/poisearch/',true);
xhr.setRequestHeader('haha',1);
xhr.send(null);

请求结果(这里OPTIONS请求触发了,但没有找到这个url):

3.服务器接收到这个请求后,根据上面的头部信息判断是否予以接收。并在响应中发送如下头部与浏览器进行沟通:

  • 表2
响应头部信息 含义
Access-Control-Allow-Origin 来源域名,与简单的请求相同。
Access-Control-Allow-Methods 允许的方法,多个方法以逗号分隔。
Access-Control-Allow-Headers(可选) 允许的头部,多个头部以逗号分隔。
Access-Control-Max-Age 应该将这个Preflight请求缓存多长时间(以秒表示)

4.Preflighted Request结束后,结果将按照指定的时间缓存起来。

5.如果服务端判断上面设置的额外信息可以允许请求,那么就会再请求一次正常的请求了。

最新文章

  1. css控制标题长度超出部分显示省略号
  2. 关于SUID、SGID、Sticky
  3. meta标签详解(meta标签的作用)///////////////////////////转
  4. 安装package.js
  5. 用Delphi实现文件关联
  6. C Socket Programming for Linux with a Server and Client Example Code
  7. 2014年6月5日 深圳 IBM 安全解决方案会议通知
  8. linux c 系统报错
  9. yum安装jdk
  10. Android Lint的使用
  11. ATS缓存数据结构
  12. 用ASP.NET Core 2.0 建立规范的 REST API -- DELETE, UPDATE, PATCH 和 Log
  13. AtCoder Grand Contest 012
  14. malloc和calloc用法
  15. golang sqlite3 CRUD
  16. 洛谷P4549裴蜀定理
  17. 干货:Java并发编程系列之volatile(二)
  18. LwIP:处理链路状态改变
  19. R及Rstuio下载及配置,及基本使用介绍
  20. 2011年入侵 Kernel.org 的黑客被捕 面临10年监禁

热门文章

  1. JAVA框架 Mybaits
  2. Android-ProgressDialog点击对话框外部是不让其消失
  3. 优化ansible速度
  4. (三)Lua脚本语言入门(数组)
  5. 大页内存(HugePages)
  6. Centos7-kafka-2.12安装验证
  7. 微服务RPC框架选美
  8. 2017-2018-2 20155315《网络对抗技术》Exp6 :信息搜集与漏洞扫描
  9. EAS_BI(扩展报表)
  10. CSS技巧收集——毛玻璃效果