Skip to content

CORS解决Ajax跨域问题

CORS概述

CORS全称:Cross-Origin Resource Sharing(跨域资源共享),是用于控制跨域请求的一套规范,服务器依照CORS规范,添加特定来控制浏览器校验,大致规则如下:

  • 服务器明确表示请求,或,则浏览器校验
  • 服务器明确表示请求,则浏览器校验

备注说明

使用CORS解决跨域是,且要求服务器是【自己人】。

CORS解决跨域

整体思路:服务器在给出响应时,通过添加响应头,来明确表达允许某个源发起跨域请求,随后浏览器在校验时,直接通过。

CORS解决跨域

服务端核心代码(以express框架为例):

js
// 处理跨域中间件
function corsMiddleWare(req,res,next){
  // 允许 http://127.0.0.1:5500 这个源发起跨域请求
  // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
  
  // 允许所有源发起跨域请求
  res.setHeader('Access-Control-Allow-Origin','*')
  next()
}

// 配置路由并使用中间件
app.get('/',corsMiddleWare,(req,res)=>{
  res.send('hello!')
})

简单请求与复杂请求

CORS会把请求分为两类,分别是:①简单请求、②复杂请求。

简单请求复杂请求
✅请求方法(method)为:GET、HEAD、POST1. 不是,就是复杂请求。
2.复杂请求会自动发送
✅请求头字段要符合《CORS 安全规范
简记:只要不手动修改请求头,一般都能符合该规范。
✅请求头的Content-Type的值只能是以下三种:
+ text/plain
+ multipart/form-data
+ application/x-www-form-urlencoded

关于预检请求:

  1. 发送时机:预检请求在实际之前发出,是由的。
  2. 主要作用:用于向服务器是否允许接下来的跨域请求。
  3. 基本流程:先发起OPTIONS请求,如果实际的跨域请求。
  4. 请求头内容:一个OPTIONS预检请求,通常会包含如下
请求头含义
Origin发起请求的源
Access-Control-Request-Method实际请求的 HTTP 方法
Access-Control-Request-Headers实际请求中使用的自定义头(如果有的话)

CORS解决跨域

  1. 第一步:服务器先浏览器的,服务器需要返回如下
响应头含义
Access-Control-Allow-Origin允许的源
Access-Control-Allow-Methods允许的方法
Access-Control-Allow-Headers允许的自定义头
Access-Control-Max-Age预检请求的结果缓存时间(可选)

CORS解决跨域

  1. 第二步:处理实际的(与处理简单请求跨域的方式相同)

CORS解决跨域

服务端核心代码:

js
// 处理预检请求
app.options('/students', (req, res) => {
  // 设置允许的跨域请求源
  res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  // 设置允许的请求方法
  res.setHeader('Access-Control-Allow-Methods', 'GET')
  // 设置允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'school')
  // 设置预检请求的缓存时间(可选)
  res.setHeader('Access-Control-Max-Age', 7200)
  // 发送响应
  res.send()
})

// 处理实际请求
app.get('/students', (req, res) => {
  // 设置允许的跨域请求源
  res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  // 随便设置一个自定义响应头
  res.setHeader('abc',123)
  // 设置允许暴露给客户端的响应头
  res.setHeader('Access-Control-Expose-Headers', 'abc')
  // 打印请求日志
  console.log('有人请求/students了')
  // 发送响应数据
  res.send(students)
})

借助cors库快速完成配置

提示

上述的配置中需要自己配置响应头,或者需要自己手动封装中间件,借助cors库,可以更方便完成配置。

  • 安装cors
shell
npm i cors
  • 简单配置cors
js
app.use(cors())
  • 完整配置cors
js
// cors中间件配置
const corsOptions = {
  origin: 'http://127.0.0.1:5500', // 允许的源
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允许的方法
  allowedHeaders: ['school'], // 允许的自定义头
  exposedHeaders: ['abc'], // 要暴露的响应头
  optionsSuccessStatus: 200 // 预检请求成功的状态码
};

app.use(cors(corsOptions)); // 使用cors中间件