我们知道借助Access-Control-Allow-Origin响应头字段可以允许跨域 AJAX, 对于非简单请求,CORS 机制跨域会首先进行 preflight(一个 OPTIONS 请求), 该请求成功后才会发送真正的请求。 这一设计旨在确保服务器对 CORS 标准知情,以保护不支持 CORS 的旧服务器。

简单请求

简单请求具体是指请求方法是简单方法且请求头是简单头的 HTTP 请求。具体地,

简单方法包括GET, HEAD, POST

简单头包括:Accept, Accept-LanguageContent-Language,以及值为application/x-www-form-urlencoded, multipart/form-data, text/plain 其中之一的 Content-Type 头。

对于非简单请求浏览器会首先发送 OPTIONS 请求(成为 preflight), 例如添加一个自定义头部x-foo的 HTTP 请求:

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('x-foo', 'bar');
xhr.send();

服务器需要成功响应(2xx)并在Access-Control-Alow-Headers中包含x-foo (因为它不是简单头部):

OPTIONS /origin-redirect-with-preflight 200
Access-Control-Allow-Headers: x-foo
Access-Control-Allow-Origin: http://index.com:4001
Connection:keep-alive
Content-Length: 0
Access-Control-Request-Headers

Access-Control-Request-Headerspreflight 请求中用来标识真正请求将会包含哪些头部字段, preflight 请求本身不会发送这些头字段。 例如上述请求中Access-Control-Request-Headers字段的值应该是x-foo。 服务器应当在对应的Access-Control-Allow-Headers响应头中包含这些字段。 否则即使返回 200 preflight 也会失败:

XMLHttpRequest cannot load http://mid.com:4001/access-control-allow-origin-wildcard.

Request header field x-foo is not allowed by Access-Control-Allow-Headers in preflight response.

关于 DNT 请求头

有些浏览器(如 Safari 隐身模式)会在请求中添加DNT头, 但浏览器不会(也不应)因此而发起 preflight。 因为这一请求头是浏览器添加的,也应当对此知情。 所以响应头中也不需要包含Access-Control-Allow-Headers, 参照 W3C Recommendation,满足以下条件即可跳过 preflight:

For request method there either is a method cache match or it is a simple method and the force preflight flag is unset. For every header of author request headers there either is a header cache match for the field name or it is a simple header.

注意只要所有Author Header是简单头即可跳过,这里的DNT虽然不是简单头但它属于 User-Agent Header。 注意在 CORS 被重定向之后这一状况会变得复杂,在重定向 CORS 跨域请求一文有较详细的讨论。

CORS 跨域中的 preflight 请求的更多相关文章

  1. CORS跨域带来的preflight request

    CORS跨域带来的preflight request https://blog.csdn.net/baidu_35407267/article/details/79043515 HTTPS://blo ...

  2. CORS跨域限制以及预请求验证

    之前我们可以通过“Access-Control-Allow-Origin”,实现跨域请求,那是不是所有跨域请求都可以通过设置Access-Control-Allow-Origin实现跨域请求呢?显然不 ...

  3. ajax跨域通过 Cors跨域资源共享 进行GetPost请求

    using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...

  4. JSONP跨域和CORS跨域

    什么是跨域? 跨域:指的是浏览器不能执行其它网站的脚本,它是由浏览器的同源策略造成的,是浏览器的安全限制! 同源策略 同源策略:域名.协议.端口均相同. 浏览器执行JavaScript脚本时,会检查这 ...

  5. CORS跨域请求规则以及在Spring中的实现

    CORS: 通常情况下浏览器禁止AJAX从外部获取资源,因此就衍生了CORS这一标准体系,来实现跨域请求. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origi ...

  6. CORS——跨域请求那些事儿

    在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on th ...

  7. CORS跨域请求

    一.问题: 服务器端代码 from flask import Flask from flask import make_response from flask import jsonify app = ...

  8. [转] 重定向 CORS 跨域请求

    非简单请求不可重定向,包括第一个preflight请求和第二个真正的请求都不行. 简单请求可以重定向任意多次,但如需兼容多数浏览器,只可进行一次重定向. 中间服务器应当同样配置相关 CORS 响应头. ...

  9. CORS跨域请求总结

    CORS跨域请求分为简单请求和复杂请求. 1. 简单请求: 满足一下两个条件的请求. (1) 请求方法是以下三种方法之一: HEAD GET POST (2)HTTP的头信息不超出以下几种字段: Ac ...

随机推荐

  1. vue子组件使用自定义事件向父组件传递数据

    使用v-on绑定自定义事件可以让子组件向父组件传递数据,用到了this.$emit(‘自定义的事件名称’,传递给父组件的数据) <!DOCTYPE html> <html lang= ...

  2. Eclipse快速入门:远程调试Java应用

    Eclipse快速入门:远程调试Java应用 2012年03月27日00:00 it168网站原创 作者:皮丽华 编辑:皮丽华 我要评论(0) 标签: Eclipse , Java , Java框架, ...

  3. python 简单主机批量管理工具

    需求: 主机分组 主机信息配置文件用configparser解析 可批量执行命令.发送文件,结果实时返回,执行格式如下  batch_run  -h h1,h2,h3   -g web_cluster ...

  4. Java运行 Unsupported major.minor version 51.0 错误

    今天写了简单的Java程序,运行的时候不知道为啥出现这个问题 happy@happy-HP-Compaq-dx7518-MT:~/Study/CrazyJava$ java FieldTest Exc ...

  5. Event Loop事件循环,GET!

    JS中比较让人头疼的问题之一要算异步事件了,比如我们经常要等后台返回数据后进行dom操作,又比如我们要设置一个定时器完成特定的要求.在这些同步与异步事件里,异步事件肯定是在同步事件之后的,但是异步事件 ...

  6. 《前端面试加分项目》系列 企业级Vue瀑布流

    本文 GitHub github.com/ponkans/F2E 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习.文末有福利~~ 前言 接水怪又来 ...

  7. Pycharm+PyQt5开发环境配置

    一.安装Python开发环境 python官网下载地址:https://www.python.org/downloads/ 注:千万不要使用最新测试版,很有可能第三方库不支持 笔者目前使用的版本是3. ...

  8. php表单提交后再后退 内容则默认清空的解决方法

    转载原文地址: http://www.jquerycn.cn/a_14422 在session_start()之后,字符输出之前加上header("Cache-control: privat ...

  9. 【Amaple教程】6. 路由配置

    在 第1节<启动路由> 章节中为了能让单页应用顺利跑起来,我们提前介绍了简单的路由配置方法.我们已了解路由配置的目的是指定不同的url下对应的 模块节点(也叫做模块容器)内应该显示哪个模块 ...

  10. JS的类

    JS在创建之初不支持类,因为很多开发者为处理类创建了好多代码库,最终导致ES6引入了类. ES5及更早的版本都不支持类,与类最接近的是:创建一个构造器,然后将方法指派到该构造器的原型上.就是原型继承. ...