当前位置: 首页 > news >正文

前端 CORS 深度解析

1. 什么是 CORS?

CORS(Cross-Origin Resource Sharing,跨域资源共享)是一种浏览器的安全机制,用于限制从一个源(协议 + 域名 + 端口)加载的脚本去请求另一个源的资源。

它的核心目标是 保护用户数据安全,避免恶意网站随意请求用户隐私数据。


2. 简单请求与非简单请求

在 CORS 中,请求分为两类:

2.1 简单请求(Simple Request)

满足以下所有条件时,才算简单请求:

  1. 请求方法:只能是 GETHEADPOST
  2. 允许的请求头:只能是以下几种(开发者可设置):
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(但值必须受限,见下条)
    • Range(且仅允许简单范围值,如 bytes=256-bytes=127-255
  3. Content-Type 限制:只能是以下三种之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded
  4. XHR 上传限制:如果使用 XMLHttpRequest,不能在 xhr.upload 上注册事件监听器。

如果满足这些条件,浏览器会 直接发请求,不会发 OPTIONS 预检。


2.2 非简单请求(Preflighted Request)

只要不满足上述条件之一,就会被认为是非简单请求,浏览器会先发 OPTIONS 预检请求,确认服务器允许后才发真正的请求。

常见触发预检的场景:

  • 使用了 PUTDELETEPATCH 等方法
  • 自定义请求头(如 X-TokenAuthorization
  • Content-Type: application/json
  • 使用了 xhr.upload.addEventListener 监听上传进度

3. 浏览器自动带的请求头

即使前端没有写任何 header,浏览器也会自动加一些,例如:

  • accept: */*
  • accept-encoding: gzip, deflate, br, zstd
  • accept-language: zh-CN,zh;q=0.9
  • cache-control: no-cache
  • connection: keep-alive
  • host: localhost:3000
  • origin: http://localhost:5173
  • pragma: no-cache
  • referer: http://localhost:5173/
  • sec-ch-ua(客户端 UA Hints)
  • sec-fetch-*(安全上下文)
  • user-agent

这些属于 浏览器自动设置的“禁用头”,开发者不能随意改动,也不会导致请求从简单请求变成预检请求。


4. Vue + Vite + Koa 跨域问题

4.1 场景

  • 前端:Vite 开发服务器,运行在 http://localhost:5173
  • 后端:Koa 服务,运行在 http://localhost:3000
  • 请求fetch("http://localhost:3000/api")

因为端口不同,构成跨域,请求会被浏览器拦截。

4.2 解决方案

方式 1:Koa 端配置 CORS

安装依赖:

npm install @koa/cors

app.js 中使用:

const Koa = require("koa");
const cors = require("@koa/cors");const app = new Koa();app.use(cors({origin: "http://localhost:5173",credentials: true,allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],allowHeaders: ["Content-Type", "Authorization"]
}));app.listen(3000);
方式 2:Vite 配置代理(开发环境推荐)

vite.config.js 中:

export default defineConfig({server: {proxy: {"/api": {target: "http://localhost:3000",changeOrigin: true,rewrite: path => path.replace(/^\/api/, "")}}}
});

请求时改成:

fetch("/api/xxx");

这样请求走 5173,同源,Vite 再转发到 3000。


5. 总结

  1. CORS 是浏览器的安全机制,保护用户免受跨站攻击。
  2. 简单请求无需预检,非简单请求需要预检(OPTIONS)。
  3. 浏览器自动加的头(Accept、User-Agent、Origin 等)不会破坏简单请求判定。
  4. 本地开发常用 代理服务端允许跨域 两种方式解决问题。
  5. 生产环境更推荐服务端配置 CORS,开发环境推荐前端代理。

6. Vite 代理与 API_BASE_URL 的关系

6.1 为什么请求还是带 http://localhost:3000/api

如果在前端代码里这样写:

fetch("http://localhost:3000/api/login")

就会直连后端 3000 端口,绕过 Vite 代理,自然还是跨域。

因为 Vite 代理只会拦截以 /api 开头的相对路径,不会拦截完整 URL。

6.2 正确用法

  • 在开发环境中,只写相对路径:

    fetch("/api/login", { ... })
    

    这样才会走 Vite 代理 → 转发到 http://localhost:3000/login

  • 在生产环境中,可以写成真实后端地址:

    fetch("https://your.prod.server/login", { ... })
    

6.3 环境变量配置

推荐在 Vite 中使用 .env 文件来区分:

.env.development

VITE_API_BASE_URL=/api

.env.production

VITE_API_BASE_URL=https://your.prod.server

前端代码:

fetch(`${import.meta.env.VITE_API_BASE_URL}/login`, {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({ username, password })
})

6.4 总结

  • 开发环境/api → 命中代理,转发到后端 3000 端口。
  • 生产环境:真实后端地址 → 直接请求后端服务。
  • 切记:如果写死 http://localhost:3000/...,代理不会生效,CORS 错误依旧存在。
http://www.dtcms.com/a/407467.html

相关文章:

  • HT81696 概述
  • PMP-项目管理-PMBOK第六版_中文版:引论
  • 上海网站建站建设自己做的网站在百度怎么发布
  • SpringBoot+QQ 邮箱邮件开发指南:环境配置、功能实现、异常处理一站式搞定
  • Linux 数据库 Mysql8 主从复制
  • 做网站的图片房产国内免费推广网站
  • 建设网站需要分析什么条件云南软件开发项目管理
  • OpenHands+cpolar:AI编程助手的远程调试新方案
  • 从 0 到 1 掌握 ESP32 RMT(新手友好版)
  • 做设计什么网站可以兼职网站管理与建设总结
  • 少样本学习学习论文分享:多模态性帮助单模态性
  • 深入MySQL底层2-SQL优化与数据库运维管理
  • 设计站网页制作的公司选时代创信
  • 国外服装网站石岩做网站哪家好
  • 超越单边控制:介绍新一代对话智能体评测基准τ2-Bench
  • Scala • basis
  • vi设计公司深圳企业网站排名怎么优化
  • 深度学习视角下的图像分类技术体系总结
  • mysql数据库最新版下载,安装
  • 记2831.找出最长等值子数组 练习理解
  • 优秀网站作品下载免费广告设计模板网站
  • 住房和城乡建设部官方网站发布郑州发布会最新消息
  • 中国建站公司重庆装修公司网站建设
  • 怎样建网站域名公司建网站多少钱合适
  • 学习峰岹MOTORSIM(Day4)——电机磁铁变弱,转速反而飙升?
  • 网页搜索记录怎么删除神马seo服务
  • interface g0/0/0.1 概念及题目
  • 网站首页引导页 模版银行官网登录入口
  • 网站运营代理淘宝网站建设违规吗
  • 基于岗课赛证的中职物联网专业“综合布线课程”教学解决方案