CORS 跨域请求的简单和预检请求

156 阅读2分钟

浏览器的同源策略

CORS

Cross-Origin Resource Sharing

CORS是一套机制,用于浏览器校验跨域请求

它的基本理念是:

只要服务器明确表示允许,则校验通过

服务器明确拒绝没有表示,则校验不通过

使用CORS方案的前提,必须保证服务器是自己人

简单请求和预检请求

CORS将请求分为两类:

简单请求

  • 请求方法为: GET HEAD POST

  • 头部字段满足CORS安全规范,详见 w3c

    一般不去改动请求头部,就是满足安全规范的。

  • 请求头的 Content-Type为

    text/plain

    multipart/form-data

    application/x-www-formrlencoded

预检请求(非简单请求)

不满足以上简单请求的

测试题

//下面的跨域请求哪些是简单请求,哪些是预检请求?

//1
fetch('https://baidu.com');

//2
fetch('https://baidu.com',{
 headers:{
  a:1
 }
});

//3
fetch('https://baidu.com', {
 method:'post',
 body:JSON.stringify({a:1,b:2})
});

//4
fetch('https://baidu.com', {
 method:'post',
 headers:{
  'content-type': 'application/jsons'
 },
  body:JSON.stringify({a:1,b:2})
});

答案 1.简单,2.预检,3.简单,4.预检

简单请求的校验

image-20240224125325998

  1. 浏览器请求时发现跨域,会带上一个请求头,origin:http://my.com,表达的是当前页面源,我从哪个源发送这个跨域请求。

  2. 浏览器校验后通知浏览器结果是否自己人。

    返回响应头Access-Control-Allow-Origin:http://my.com或不指定源Access-Control-Allow-Origin:*表示所有源都通过。

预检请求的校验

image-20240224125951538

  1. 浏览器在正式发送跨域请求前,会先询问服务器,也就是预检请求,通过后才会正式发送真实请求。

  2. 预检请求请求方法是: OPTIONS携带以下请求头

    Origin:http://my.com

    Access-Control-Request-Method: POST

    Access-Control-Request-Headers:a, b, content-type

  3. 服务器会返回其允许的返回头参数

    ``Access-Control-Allow-Origin:my.com`

    Access-Control-Request-Methods: POST

    Access-Control-Request-Headers:a, b, content-type

    Access-Control-MAX-Age: 86400 (表示86400秒以内不用再问,都是这套返回头,可以把它缓存起来)

  4. 通过后发送真实请求

    跟简单请求一致

CORS问题

image-20240224131607619

分析答案

  1. 不能,CORS需要动服务器。除非小王自己去写个前端服务器

  2. 不能,必须要保证服务器是自己人

  3. 有可能发生。

    上传图片的请求头是简单请求POST ,multipart/form-data,

    说明服务器支持简单请求,提交普通表单跨域,表单数据格式一般是JSON,会修改请求头content-type:application/json,请求变为预检请求。不通过说明不支持预检请求

记录学习笔记