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

浏览器访问跨域 - 教程

文章目录

  • 发现问题
    • 浏览器 vs Postman 跨域行为差异原理
  • CORS
    • 工作流程
    • 响应头详解
  • 总结

发现问题

在Web应用开发过程中,前端页面通过浏览器调用第三方API接口时,触发了跨域资源共享(CORS)限制,导致请求被拦截。具体报错信息如下:blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
首先使用Postman测试接口,确认接口本身正常可用。进一步研究发现,Postman作为API测试工具不受浏览器同源策略限制,而浏览器环境存在CORS安全机制。

浏览器 vs Postman 跨域行为差异原理

  1. 核心原理对比
特性浏览器Postman
同源策略✅ 强制执行❌ 不执行
CORS 机制✅ 必须遵守❌ 不需要
安全沙箱✅ 有❌ 无
应用场景用户日常上网开发者调试工具
  1. 技术层面的差异
    浏览器的安全机制:

Postman 的本质:

CORS

CORS(Cross-Origin Resource Sharing,跨源资源共享) 是一种基于 HTTP 头的机制,允许服务器指定哪些源(协议+域名+端口)可以访问其资源。

// "源" 的定义
const origin = protocol + "://" + hostname + ":" + port;
// 同源示例
const origin1 = "https://example.com:443";  // 默认端口可省略
const origin2 = "https://example.com";      // 同源
// 不同源示例
"http://example.com"    // 协议不同 (http vs https)
"https://api.example.com"  // 子域名不同
"https://example.com:8080" // 端口不同

工作流程

服务器浏览器客户端服务器浏览器客户端发起跨域请求alt[简单请求][预检请求]fetch('https://other.com/api', options)直接发送真实请求Origin: https://client.com响应 + CORS 头根据 CORS 头决定是否返回响应OPTIONS 预检请求Origin: https://client.comAccess-Control-Request-Method: POSTAccess-Control-Request-Headers: X-Custom204 No Content + CORS 头发送真实请求真实响应 + CORS 头返回响应数据

响应头详解

响应头必需/可选作用示例场景
Access-Control-Allow-Origin⭐ 必需允许的来源https://frontend.com所有跨域请求
Access-Control-Allow-Methods⭐ 预检必需允许的HTTP方法GET, POST, OPTIONS预检请求(OPTIONS)响应
Access-Control-Allow-Headers⭐ 预检必需允许的请求头Content-Type, Authorization预检请求中使用了非简单头部
Access-Control-Allow-Credentials⭐ 凭证必需是否允许凭证true请求需要携带凭证(cookies、认证头)
Access-Control-Expose-Headers✅ 可选暴露的响应头X-Total-Count需要前端访问自定义响应头时
Access-Control-Max-Age✅ 可选预检缓存时间86400 (缓存 24 小时)优化性能,减少预检请求
Vary: Origin✅ 推荐缓存区分Origin
  1. Access-Control-Allow-Origin
    作用: 指定允许访问资源的来源
    详细说明:

    • 允许所有域名(最简单,但不安全)
    • http://example.com:允许特定域名
    • http://localhost:8080:允许本地开发服务器

    示例:

    # 语法
    Access-Control-Allow-Origin:  | *
    # 示例
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Origin: http://localhost:3000

    浏览器行为:

    客户端请求头:Origin: http://localhost:8080
    服务器响应头:Access-Control-Allow-Origin: http://localhost:8080
    ✓ 匹配成功,允许访问
  2. Access-Control-Allow-Methods
    作用: 允许客户端使用哪些 HTTP 方法。
    详细说明:

    • OPTIONS 必须包含,用于预检请求
    • 常用的 RESTful 方法:
      • GET:获取资源
      • POST:创建资源
      • PUT:更新资源
      • DELETE:删除资源
      • PATCH:部分更新(可选)
      • HEAD:获取头部信息(可选)

    示例:

# 语法
Access-Control-Allow-Methods: <method>[, <method>]*# 示例Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
  1. Access-Control-Allow-Headers
    作用: 允许客户端发送哪些自定义请求头
    详细说明: 当请求包含不在列表中的头部时,浏览器会阻止请求
    常见需要允许的头部:

    头部作用是否必需
    Authorization认证令牌(Bearer token)✓ 必需
    Content-Type请求体类型(JSON/表单等)✓ 必需
    Accept客户端接受的响应类型推荐
    X-Requested-With标识 AJAX 请求推荐
    Cache-Control缓存控制可选
    X-CSRF-TokenCSRF 防护可选

    示例:

    # 语法
    Access-Control-Allow-Headers: <header-name>[, <header-name>]*# 示例Access-Control-Allow-Headers: Content-Type, Authorization# 浏览器发送的预检请求OPTIONS /api/data HTTP/1.1Access-Control-Request-Headers: Content-Type, X-Custom-HeaderOrigin: https://frontend.com# 服务器响应必须包含这些头Access-Control-Allow-Headers: Content-Type, X-Custom-Header
  2. Access-Control-Allow-Credentials
    作用: 是否允许携带凭证(cookies、HTTP认证)
    重要规则:

    • 不能与 Access-Control-Allow-Origin: * 同时使用
    • 必须与具体的域名配合

    语法:

    Access-Control-Allow-Credentials: true | false
  3. Access-Control-Expose-Headers
    作用: 允许浏览器访问哪些响应头
    背景: 默认情况下,浏览器只能访问以下"简单响应头":
    Cache-Control
    Content-Language
    Content-Type
    Expires
    Last-Modified
    Pragma
    其他头部(如自定义头部)需要显式暴露。

    # 语法
    Access-Control-Expose-Headers: <header-name>[, <header-name>]*# 示例:暴露自定义头Access-Control-Expose-Headers: X-Total-Count, X-Custom-Header# 前端可以访问fetch('/api/data').then(response => {console.log(response.headers.get('X-Total-Count'));  // ✅ 可以访问console.log(response.headers.get('X-Custom-Header')); // ✅ 可以访问});
  4. Access-Control-Max-Age
    作用: 预检请求的缓存时间(秒)

    # 语法
    Access-Control-Max-Age: <delta-seconds># 示例Access-Control-Max-Age: 86400  # 缓存 24 小时Access-Control-Max-Age: 600    # 缓存 10 分钟# 效果:# 1. 浏览器缓存预检响应结果# 2. 在有效期内,相同请求不再发送预检请求# 3. 减少网络请求,提高性能# 建议值:# - 开发环境:300(5分钟)# - 生产环境:86400(24小时)
  5. Vary
    作用: 正确缓存不同来源的响应

    # ❌ 没有设置 Vary: Origin,可能导致缓存污染
    # 用户A访问后,用户B可能看到A的CORS设置
    # ✅ 正确配置
    Access-Control-Allow-Origin: https://frontend.com
    Vary: Origin

总结

CORS 错误总是服务器配置问题,浏览器只是在执行安全策略保护用户安全。

调整后测试环境CORS配置:

<httpProtocol><customHeaders><add name="Access-Control-Allow-Origin" value="*" /><add name="Access-Control-Allow-Credentials" value="false" /><add name="Access-Control-Allow-Headers" value="*" /><add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /><add name="Access-Control-Expose-Headers" value="*" /></customHeaders>
</httpProtocol>
http://www.jsqmd.com/news/387644/

相关文章:

  • 开放式厨房适合装集成灶吗?高吸力集成灶选购指南|吸油烟黑科技揭秘 - 匠言榜单
  • 题解:洛谷 P5738 【深基7.例4】歌唱比赛
  • vue2项目改造为vue3遇到的问题以及解决办法
  • 信息论与编码篇---马氏距离
  • 题解:洛谷 P5736 【深基7.例2】质数筛
  • 题解:洛谷 P5735 【深基7.例1】距离函数
  • 单北斗变形监测在大坝安全和地质灾害预警中的应用与优势
  • 长豆荚目标检测:Faster R-CNN改进模型实战与优化 - 教程
  • 【每日一题】LeetCode 190. 颠倒二进制位
  • AVIF 如何转 PNG?几种常见在线转换方案对比
  • C++中的指针 之二
  • C++中的指针 之一
  • 2026最新AI大模型应用开发的核心技术学习线路看这里,程序员小白必看:大模型应用开发,收藏这份超全学习指南!
  • WebFlux vs MVC:Gateway集成若依框架的技术选型之争 - 实践
  • 掌握应用开发学习路线,大模型开发入门指南:小白也能轻松掌握的AI应用开发流程与实战(收藏版)
  • C++中的指针
  • prompt实践
  • AI_Agent也有体检中心了?AgentDoG开源框架,带你入门智能体安全防护
  • GLM-5与MiniMax-M2.5性能对比,小白程序员必看(收藏版)
  • CppCon 2025 学习:C++23 deducing this
  • 2026 Agent元年!小白程序员必备:大模型学习路线图+精选资源,收藏这份高薪指南!
  • AI大模型从入门到精通:小白程序员必备学习路线(2026最新版)
  • 导师严选!继续教育专用AI论文软件 千笔·专业学术智能体 VS 学术猹
  • Comsol流固耦合注浆及冒浆分析。 采用其中达西定律模块及固体力学模块,通过建立质量源项、体...
  • 信息论与编码篇---欧式距离
  • 学长亲荐!更贴合研究生需求的降AI率平台,千笔·降AI率助手 VS 云笔AI
  • 导师严选! AI论文平台 千笔写作工具 VS WPS AI 更贴合自考需求
  • [NOIP2025 T2] 清仓甩卖 题解
  • 告别低效繁琐!降AI率平台 千笔·专业降AI率智能体 VS 文途AI
  • 实测对比后!千笔·专业学术智能体,专科生论文写作神器