一、简介

CORS(跨域资源共享 Cross-origin resource sharing)是实现跨域的一种常用方式。实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信

二、CORS的两种请求

(1)简单请求(simple request

(2)非简单请求(not-so-simple request)

简单请求必须同时满足以下两大条件:

1、请求方式是:GETPOSTHEAD中的一种

2、http请求头限制为这几种字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:只限于三个值application/x-www-form-urlencoded(表单提交格式)multipart/form-data(文件上传格式)text/plain(纯文本格式)

凡是不同时满足上面两个条件,就属于非简单请求。

三、浏览器对简单请求的处理方式

对于简单请求,浏览器直接发出CORS请求。即在请求头信息之中,增加一个Origin字段(Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口))。

服务器通过Origin值来判断是否接受此次请求。

如果同意:则服务器返回响应

响应头会多出以下几个信息字段

Access-Control-Allow-Origin

Access-Control-Allow-Credentials

Content-Type: text/html

如果服务器拒绝:服务器会返回一个正常的HTTP回应(http状态吗有可能是200,所以无法通过状态码判断此类错误),响应头中不包含Access-Control-Allow-Origin字段,浏览器没有接收到Access-Control-Allow-Origin字段时就会抛出一个错误,被XMLHttpRequestonerror回调函数捕获。

四、浏览器对非简单请求的处理方式

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

CORS非简单请求会在正式通信之前,增加一次HTTP请求,称为“预检”请求。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,服务器允许之后,浏览器才会发出正式的XMLHttpRequest请求,否则会报错。

"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。

预检请求请求头一般包含这几个字段信息

1、Origin:   关键字段(必需),表示请求来自哪个源

2、Access-Control-Request-Method :该字段是必需的,用来列出浏览器的CORS请求会用到哪些HTTP方法

3、Access-Control-Request-Headers:该字段可选,是一个用逗号分隔的字符串,指定浏览器CORS请求会额外发送的请求头信息字段

预检请求的回应:

(1)服务器确认允许跨源请求

服务器做出相应的响应,返回的响应头信息中包含以下几项重要信息字段:

1、Access-Control-Allow-Origin(该字段是必需的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。)

2、Access-Control-Allow-Methods(该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法)

3、Access-Control-Allow-Headers(如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段)

、Access-Control-Allow-Credentials(该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。)

5、Access-Control-Max-Age(该字段可选,用来指定本次预检请求的有效期,单位为秒。)

一旦服务器通过了“预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样。

PS:如下两张图是“预检”请求和正式请求http的一些响应

图一、“预检”请求

图二、正式请求

(2)服务器不同意预检请求

如果浏览器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会报出以下错误:

XMLHttpRequest cannot load ...(这里是要访问的来源)

Origin ...(这里是要访问的来源) is not allowed by Access-Control-Allow-Origin.

CORS请求的更多相关文章

  1. 从零开始学 Java - Spring 支持 CORS 请求踩的坑

    谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...

  2. 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求

    论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...

  3. Java - Spring MVC 实现跨域资源 CORS 请求

    拦截器设置响应头 这种方式原理就是利用拦截器在方法执行前,我们增加请求的响应头,用来支持跨域请求.这种方案是可行的,大部分都是采用这种方案.我当时也是打算采用这种方案,直到我发现原来 Spring 框 ...

  4. Spring MVC 实现跨域资源 CORS 请求

    说到 AJAX 跨域,很多人最先想到的是 JSONP.的确,JSONP 我们已经十分熟悉,也使用了多年,从本质上讲,JSONP 的原理是给页面注入一个 <script>,把远程 JavaS ...

  5. Angular2,Springboot,Zuul,Shiro跨域CORS请求踩坑实录

    前言:前后端分离,业务分离,网关路由等已经成为当下web application开发的流行趋势.前端以单页面路由为核心的框架为主体,可以单独部署在nodejs或nginx上.后端以springboot ...

  6. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  7. 利用CORS实现跨域请求(转载)

    跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题.不过现在,我们可以考虑一下W3C中一项新的特性--CORS(Cross-Origin Resource Sh ...

  8. 解决ajax请求cors跨域问题

    ”已阻止跨源请求:同源策略禁止读取位于 ***** 的远程资源.(原因:CORS 头缺少 'Access-Control-Allow-Origin').“ ”已阻止跨源请求:同源策略禁止读取位于 ** ...

  9. Java实现CORS跨域请求

    问题 使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据 这是由于浏览器的同源策略导致的,目的是为了安全.在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同 ...

随机推荐

  1. yum localinstall 安装mysql8.0

    MySQL :: MySQL 8.0 Reference Manual :: 2.5.1 Installing MySQL on Linux Using the MySQL Yum Repositor ...

  2. In ZeroDB, the client is responsible for the database logic. Data encryption, decryption, and compression also happen client side. Therefore, the server never has any knowledge about the data, its str

    zerodb/index.rst at master · zerodb/zerodb https://github.com/zerodb/zerodb/blob/master/docs/source/ ...

  3. Windows:子线程中创建窗口

    一般来讲,UI的所有操作都必须在主线程,否则会出现未知错误.但有时候我们会需要一个功能比较单一的窗口,同时希望他在一个单独的线程运行.并不影响主线程的效率. 下面说明一下新建子线程创建的新窗口的方法, ...

  4. [py][lc]python高阶函数(匿名/map/reduce/sorted)

    匿名函数 - 传入列表 f = lambda x: x[2] print(f([1, 2, 3])) # x = [1,2,3] map使用 传入函数体 def f(x): return x*x r ...

  5. eclipse恢复默认布局

    eclipse恢复默认布局 Window (->Perspective ->) Reset Perspective

  6. visio基础教程(一)

  7. MyBatis—mybatis-config.xml配置介绍

    在定义sqlSessionFactory时需要指定MyBatis主配置文件: Xml代码   说明: 收藏代码 1.  <bean id="sqlSessionFactory" ...

  8. ACM ICPC, JUST Collegiate Programming Contest (2018) Solution

    A:Zero Array 题意:两种操作, 1 p v  将第p个位置的值改成v  2  查询最少的操作数使得所有数都变为0  操作为可以从原序列中选一个非0的数使得所有非0的数减去它,并且所有数不能 ...

  9. 常用php操作redis命令整理(五)ZSET类型

    ZADD 向有序集合插入一个元素,元素关联一个数值,插入成功返回1,同时集合元素不可以重复, 如果元素已经存在返回 0 <?php var_dump($redis->zadd(,'A')) ...

  10. constructor-arg和property的区别

    两者都是给bean注入属性,区别: constructor-arg:通过构造函数注入. property:通过setter对应的方法注入. 详情见:https://blog.csdn.net/u012 ...