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

什么是跨域访问问题,如何解决?

跨域访问问题(Cross-Origin Resource Sharing, CORS)是由浏览器的同源策略(Same-Origin Policy)引发的一种安全限制。当网页尝试从一个与自身“源”(协议、域名、端口号)不同的地址请求资源(如API数据、图片、脚本等)时,浏览器会阻止该请求,除非目标服务器明确允许这种跨域访问。


核心概念解析

  1. 同源策略(Same-Origin Policy)

    • 定义:浏览器要求网页只能访问与自身“源”相同的资源。
    • 同源判定:协议(http/https)、域名(example.com)、端口(:80)三者完全一致。
      例如:
      https://a.com/index.htmlhttps://a.com/api同源
      https://a.com/index.htmlhttp://a.com/api ❌ 协议不同(HTTPS vs HTTP)
      https://a.com/index.htmlhttps://b.com/api ❌ 域名不同
      https://a.com:80/index.htmlhttps://a.com:8080/api ❌ 端口不同
  2. 跨域场景举例

    • 前端部署在 https://web.com,调用API https://api.com/data
    • 本地开发时 http://localhost:3000 访问本地API http://localhost:8000(端口不同)。
    • 子域名不同:https://shop.example.com 访问 https://api.example.com

为什么需要跨域限制?

  1. 安全防护
    防止恶意网站通过脚本窃取用户敏感数据(如Cookie、私有数据)。例如:
    • 用户登录了 bank.com,若恶意网站 evil.com 能随意读取 bank.com 的数据,将导致账户被盗。
  2. 隔离攻击面
    限制CSRF(跨站请求伪造)、XSS(跨站脚本攻击)等漏洞的影响范围。

如何解决跨域问题?

方案1:服务端配置CORS(主流方案)

服务端在响应头中添加允许跨域的声明:

Access-Control-Allow-Origin: https://web.com   // 允许特定域名
Access-Control-Allow-Origin: *                 // 允许所有域名(慎用)
Access-Control-Allow-Methods: GET, POST, PUT   // 允许的请求方法
Access-Control-Allow-Headers: Content-Type     // 允许的请求头

流程

  1. 浏览器发送预检请求(OPTIONS)询问服务器是否允许跨域。
  2. 服务器响应允许的规则。
  3. 浏览器确认后发送真实请求。
方案2:代理服务器(Proxy)

前端通过同源代理中转请求:

浏览器 → https://web.com/proxy?target_api=xxx → 代理请求 → https://api.com/data

常用于开发环境(如Webpack DevServer代理)或后端服务中转。

方案3:JSONP(过时方案,仅限GET请求)

利用 <script> 标签不受同源策略限制的特性:

<script src="https://api.com/data?callback=handleData"></script>

服务端返回:handleData({...}),前端需提前定义 handleData 函数。


常见误区

  • “Postman能请求成功,但浏览器报CORS错误”
    → 因为Postman不受同源策略限制,浏览器才会拦截。
  • “前端代码修改请求头可以绕过CORS”
    → 浏览器会阻止前端修改敏感请求头(如Origin),必须服务端授权。

总结

关键点说明
触发原因浏览器同源策略的安全限制
本质浏览器与服务端的协作机制(通过HTTP头协商)
解决方案服务端配置CORS、代理服务器、JSONP(历史方案)
核心目标在安全前提下实现合法跨域通信

⚠️ 注意:CORS是浏览器行为,服务端即使未配置CORS,接口本身仍可被非浏览器工具(如curl、Postman)正常调用。

http://www.dtcms.com/a/327685.html

相关文章:

  • Windows怎样配置动态磁盘
  • [SC]SystemC中的SC_FORK和SC_JOIN用法详细介绍
  • android端自定义通话通知
  • VUE的8个生命周期
  • Orange的运维学习日记--41.Ansible基础入门
  • sqli-labs通关笔记-第44关 POST字符型堆叠注入(单引号闭合 手工注入+脚本注入3种方法)
  • demo 英雄热度榜 (条件筛选—高亮切换—列表渲染—日期显示)
  • Full GC 频率优化实战
  • RGWRados::get_obj_state_impl()
  • 25C机场航班调度程序(JS 100)
  • 【智能硬件】2025年儿童智能手表革命:守护隐私的科技堡垒
  • AQS的理解
  • B树索引和B+树索引有什么区别?
  • 编译 BusyBox for ARM 平台
  • 数据结构:图
  • 1、正则表达式入门
  • (LeetCode 每日一题) 2787. 将一个数字表示成幂的和的方案数(动态规划dp+01背包)
  • Python 常用的正则表达式
  • CodeRush AI 助手进驻 Visual Studio:AiGen/AiFind 亮相(五)
  • RL推理的尽头,是熵坍缩?统一SFT与强化学习的新视角
  • 零基础学Java第七讲---调试(IDEA)
  • 面试经典150题[001]:合并两个有序数组(LeetCode 88)
  • 【代码随想录day 17】 力扣 98.验证二叉搜索树
  • iis无法访问文件
  • NTP常见日志分析
  • 每日五个pyecharts可视化图表-line:从入门到精通 (4)
  • 多轮问答与指代消解
  • 测试匠谈 | AI语音合成之大模型性能优化实践
  • @JsonAnyGetter 动态表格渲染的“神”
  • 「机器学习」:金融风控贷款违约预测,天池比赛解决详细思路