返回文章列表

【踩坑】因跨域预检踩的坑——预检


最近写的项目部分接口需要跨域,我是这么做的:

  1. 先创建一个新的axios实例,新实例只负责跨域请求。
  2. 新的实例复用之前实例的拦截器。
  3. 新实例请求失败,错误信息CORS。
  4. 联系后端确认是否开启了跨域,得到肯定答复后直接用fetch(url)发现没有CORS错误。

问题分析与结论

  1. 既然fetch可以,基于XHR的axios会报错,应该是axios的配置问题。
  2. 发现在axios复用请求拦截器的时候请求头里携带了额外的字段。
  3. 因为携带了额外字段导致浏览器发请求前会先发一个preflight预检请求,该请求是options方法,预检后才会尝试发送实际的请求。
  4. 如果想让预检通过只是加跨域头是不够的,需要服务端额外处理预检请求。
  5. 以下代码来自 chatGpt,我自己跑了个demo,尝试处理预检请求。
const express = require('express');
const app = express();

// 处理预检请求的中间件
app.options('*', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.status(200).send();
});

// 处理实际请求的路由
app.get('/api/data', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  // 处理业务逻辑并发送响应
  res.json({ message: 'Hello, world!' });
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});