前端面试官:Post为什么要发送两次请求?
核心思路浏览器出于安全考虑对“非简单请求”自动发起 OPTIONS 预检以获取服务器授权性能优化的本质是“将非简单请求降级为简单请求”或“缓存预检结果”。️ 解决方案架构图文本版[客户端 Browser] [网络层] [服务端 Server] | | | | 1. 判断是否为非简单请求? | | |--(是)-----------------------| | | | | | 2. 发送 OPTIONS 预检请求 | | | (Origin, Method, Headers) | -------------------------| | | | 3. 校验CORS策略 | | | | 4. 返回预检响应 | -------------------------| | (Access-Control-Allow-*) | | | | | | 5. 检查响应头是否包含允许信息 | | |--(通过)---------------------| | | | | | 6. 发送真正的业务请求(POST等) | | | ----------------------------| | | | | | 7. 返回业务数据 | -------------------------| | | | ⚠️ 若步骤5校验失败 - 浏览器直接拦截抛出CORS Error真实请求永不发出 答案核心干货1. 纠正概念不是“两次POST”而是“1次OPTIONS 1次POST”错误认知浏览器发了两次一样的请求。正确原理这是 CORS 机制中的Preflight预检。浏览器在发送跨域的非简单请求前必须先询问服务器“我即将用 X 方法、带 Y 头访问你你允许吗”主要矛盾安全性 vs 性能。预检保障了跨域安全但增加了一次 RTT往返时延导致接口耗时翻倍。次要矛盾开发者对“简单请求”定义模糊导致无意中触发了不必要的预检。2. 触发预检的条件非简单请求判定只要满足以下任意一条即触发 OPTIONSMethod 非简单不是GET、HEAD、POST注意即使是POST也可能触发见下条。Content-Type 非简单不是application/x-www-form-urlencoded、multipart/form-data、text/plain。⚠️高频坑点application/json会触发预检。自定义请求头携带了除 CORS 安全列表以外的 Header如Authorization、X-Token、X-Requested-With。其他使用了ReadableStream、XMLHttpRequestUpload对象注册了事件监听器等。❓ 为什么 GET 很少发预检POST 却经常发GET 通常是简单请求无Body、无自定义头。POST 在现代开发中常配合application/json或Authorization头使用这两者都会将其变为“非简单请求”。3. 优化策略从根源减少/消除预检优化手段原理适用场景局限性设置 Max-Age服务端返回Access-Control-Max-Age: 86400浏览器缓存预检结果所有跨域接口受浏览器上限限制Chrome 2h/Firefox 24h仅同域名路径有效降级 Content-Type改用text/plain或form-urlencoded内部服务、表单提交后端需适配解析逻辑不适合复杂嵌套JSON避免自定义头Token 放 CookieSameSiteNone或 URL 参数对SEO或旧系统兼容要求高安全性降低Cookie 有大小限制同域部署Nginx 反向代理/api到后端前端只访问同域生产环境首选需运维配置SSR/BFF架构天然支持WebSocketWS 不受 CORS 预检限制实时通信、长连接协议不同不适合常规CRUD⚠️ 边界场景与避坑指南Max-Age 的浏览器差异Chrome: 最大缓存2小时7200s超过按2h算。Firefox: 最大缓存24小时86400s。Safari: 历史上曾限制为5分钟新版本已改善但仍需注意。建议设置86400即可无需更大。预检请求不带 CookieOPTIONS 请求默认不携带凭证服务端校验时不能依赖 Cookie 中的 Session应基于 Origin/Header 做白名单校验。Vary如果服务端根据 Origin 动态返回 CORS 头必须在响应头加Vary: Origin否则 CDN/浏览器可能缓存错误的 CORS 响应给其他源。本地调试陷阱localhost和127.0.0.1被视为不同源开发时也会触发预检不要误以为是线上问题。 示例代码服务端Node.js/Koa正确配置app.use(async(ctx,next){constoriginctx.get(Origin);// ✅ 动态白名单校验constallowedOrigins[https://app.example.com,https://admin.example.com];if(allowedOrigins.includes(origin)){ctx.set(Access-Control-Allow-Origin,origin);ctx.set(Access-Control-Allow-Credentials,true);ctx.set(Access-Control-Allow-Methods,GET,POST,PUT,DELETE,OPTIONS);ctx.set(Access-Control-Allow-Headers,Content-Type,Authorization,X-Token);// ✅ 关键优化缓存预检结果24小时ctx.set(Access-Control-Max-Age,86400);// ✅ 关键安全防止CDN缓存污染ctx.set(Vary,Origin);}// ✅ OPTIONS 直接返回204不走后续业务逻辑if(ctx.methodOPTIONS){ctx.status204;return;}awaitnext();});前端规避预检的写法对比// ❌ 触发预检application/json Authorizationfetch(/api/data,{method:POST,headers:{Content-Type:application/json,Authorization:Bearer xxx},body:JSON.stringify({name:test})});// ✅ 不触发预检需后端支持解析fetch(/api/data,{method:POST,headers:{Content-Type:text/plain},body:JSON.stringify({name:test})// 字符串形式发送}); 满分答案面试口述版“这个问题考察的是对 CORS 预检机制的理解。首先澄清浏览器发的不是两次 POST而是一次 OPTIONS 预检 一次真实请求。这是浏览器对‘非简单请求’的安全握手确认服务器允许该跨域操作后才会发送真实请求。触发条件有三类一是方法不是 GET/HEAD/POST二是 Content-Type 不是表单/纯文本比如常用的 application/json三是带了 Authorization 等自定义头。这就是为什么 POST 比 GET 更容易触发预检——因为现代 API 普遍用 JSON 和 Token。优化方案分三层最有效生产环境通过 Nginx 反代实现同域彻底消除跨域最通用服务端设置Access-Control-Max-Age: 86400缓存预检结果注意 Chrome 上限是 2 小时兜底方案将 Content-Type 降级为 text/plain 或用 Cookie 替代自定义头把请求变回简单请求。额外注意服务端动态返回 CORS 头时必须加Vary: Origin否则 CDN 缓存会导致跨域混乱。这道题表面问网络现象实际考的是安全模型、HTTP 协议细节和工程化优化能力的综合理解。”

相关新闻

医疗器械 UDI 与动力电池追溯:一物一码合规标签打印方案解析

医疗器械 UDI 与动力电池追溯:一物一码合规标签打印方案解析

引言一块动力电池从出厂到报废,可能要流转十几年;一支植入人体的医疗器械,直接关乎患者生命安全。这两类看似毫不相关的产品,如今被同一条规则串在了一起:每一件都必须有一个唯一的"身份证",并且…

2026/8/23 20:19:03 阅读更多 →
Ornith-1.5: From Self-Scaffolding to Self-Improvement——从自我脚手架搭建到自我改进

Ornith-1.5: From Self-Scaffolding to Self-Improvement——从自我脚手架搭建到自我改进

一、核心贡献Ornith-1.5 提出了一种端到端的自我改进框架,让大语言模型能够通过持续自我生成任务、构建解决方案脚手架、产出训练数据,形成一个闭环的自我提升系统。这是 Ornith-1.0 自我脚手架搭建框架的重大升级。二、技术核心:三阶段自我改…

2026/8/23 18:26:19 阅读更多 →
React面试核心考点与实战优化解析

React面试核心考点与实战优化解析

1. React面试核心考点解析 作为前端开发领域的三大主流框架之一,React的面试题往往聚焦于其独特的设计哲学和底层实现机制。我在过去三年面试过近百名React开发者,发现候选人最容易在虚拟DOM原理、组件生命周期管理和状态管理方案这三个维度暴露出知识盲…

2026/8/23 21:42:40 阅读更多 →

最新新闻

Python在芯片设计中的应用:从RTL生成到验证自动化

Python在芯片设计中的应用:从RTL生成到验证自动化

1. 项目概述:Python如何成为芯片工程师的“瑞士军刀”如果你在十年前问一个芯片设计工程师用什么工具,答案多半是清一色的EDA(电子设计自动化)厂商套件和Shell脚本。但今天,你再问同样的问题,Python几乎会出…

2026/8/24 5:18:48 阅读更多 →
HC32L136硬件IIC驱动AT24C64实战指南

HC32L136硬件IIC驱动AT24C64实战指南

1. 项目概述:为什么在HC32L136/L176上坚持用硬件IIC驱动AT24C64?我做国产MCU嵌入式开发快十二年了,从早期的ST、GD一路摸到华大半导体的HC32系列。去年接手一个低功耗工业传感器节点项目,主控选了HC32L136——超低待机电流&#x…

2026/8/24 5:18:48 阅读更多 →
微型开源项目盈利实战:从代码到月入9000美元的六步法

微型开源项目盈利实战:从代码到月入9000美元的六步法

1. 这篇文章真正要解决的问题一个开发者,花几周时间写了个小工具,开源放在GitHub上,然后呢?绝大多数故事的结局是:收获几十个star,零星几个issue,然后项目慢慢沉寂。但总有一些项目,…

2026/8/24 5:18:48 阅读更多 →
Android开发核心技能与面试指南

Android开发核心技能与面试指南

1. Android开发岗位全景透视在移动互联网蓬勃发展的今天,Android开发工程师依然是技术领域的热门岗位。根据最新的开发者调查报告显示,全球Android设备激活量已突破30亿台,国内Android开发者占比达到移动开发从业者的68%。这个岗位不仅需要扎…

2026/8/24 5:18:47 阅读更多 →
ROS2入门实战:从零搭建小海龟仿真环境与核心通信机制验证

ROS2入门实战:从零搭建小海龟仿真环境与核心通信机制验证

这次我们来看 ROS2 机器人操作系统中的“小海龟”实验。对于任何学习 ROS2 的人来说,小海龟(turtlesim)都是绕不开的第一个实操项目。它不是一个复杂的机器人,而是一个简单的图形化仿真器,但麻雀虽小,五脏俱…

2026/8/24 5:18:47 阅读更多 →
PCB设计进阶:从叠层规划到布线实战的完整指南

PCB设计进阶:从叠层规划到布线实战的完整指南

1. 项目概述:从“能跑”到“跑得好”的PCB设计进阶干了十几年硬件设计,画过的板子堆起来能当凳子坐。早些年觉得PCB设计嘛,不就是把原理图上的线连起来,能通电、信号能过去就完事了。直到后来被各种稀奇古怪的问题按在地上摩擦——…

2026/8/24 5:17:47 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →