游览器跨域问题详解

1.跨域问题产生原因

跨域(Cross-Origin)问题,指的是浏览器的同源策略(Same-Origin Policy,SOP) 限制了从一个源(Origin)访问另一个源的资源。

游览器同源策略指的是(相同协议,相同地址,相同端口)

2.同源策略的目的

为了保护用户的数据安全,防止前端网站里面的恶意请求窃取用户数据。列子如下:

(1)当用户在登录一个如银行的网站后,会缓存在游览器一些cookie或会话信息

(2)之后用户如果进入一个钓鱼网站后,网站能获取到游览器的缓存信息,然后执行一些恶意请求的代码,用于获取用户的的隐私数据。如下:

javascript 复制代码
fetch("https://bank.com/api/account", { credentials: "include" } //认证信息)
  .then(res => res.json())
  .then(data => console.log(data)); 

(3)游览器的同源策略就是为了防止这些恶意请求,从而进行拦截。除非在服务器通过配置CORS来允许这些请求。

3.解决同源策略的方式

1.通过webpack配置实现

原理:网站的请求通过webpack服务器代理向后端服务器发送数据请求,游览器只与webpack代理的服务器请求,从而避免了跨域请求。

2.通过nginx反向代理

同理也是通过nginx反向代理服务器转发请求到后端服务器,避免了游览器与后端服务器的通信。

小结:有了代理服务器后,浏览器从始至终都只与代理服务器交互,而不直接与后端服务器进行通信。

3.通过后端配置CORS

后端服务器配置CORS来告诉游览器那些请求源可以访问,让游览器不要拦截。

4.游览器拦截跨域请求的机制

  1. 简单请求(Simple Request)

对于某些简单的跨域请求(如 GETPOST 请求,且满足特定条件),浏览器会直接发送请求,但会在请求头中附加一个 Origin 字段,标明请求的来源。服务器收到请求后,需要检查 Origin 字段,并在响应头中包含 Access-Control-Allow-Origin,明确允许该来源访问。如果服务器没有返回这个响应头,或者 Access-Control-Allow-Origin 的值不匹配请求的 Origin,浏览器会拦截响应,不将其传递给前端代码。

  1. 预检请求(Preflight Request)

对于复杂的跨域请求(如使用了 PUTDELETE 方法,或者请求头中包含自定义字段等),浏览器会先发送一个 OPTIONS 请求(即预检请求),询问服务器是否允许该跨域请求。这个预检请求会包含以下信息:

  • Origin:请求的来源。
  • Access-Control-Request-Method:实际请求的方法(如 PUTDELETE 等)。
  • Access-Control-Request-Headers:实际请求中包含的自定义头。

服务器收到预检请求后,需要检查这些信息,并在响应头中返回:

  • Access-Control-Allow-Origin:允许的来源。
  • Access-Control-Allow-Methods:允许的方法。
  • Access-Control-Allow-Headers:允许的请求头。

w-Methods`:允许的方法。

  • Access-Control-Allow-Headers:允许的请求头。

如果服务器返回的响应头满足浏览器的要求,浏览器才会继续发送实际的跨域请求;否则,浏览器会直接拦截请求,不会发送实际请求。

5.通过nginx解决跨域问题两种方式

1.只加 CORS 响应头

js 复制代码
server {
    listen 80;

    location /api/ {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        add_header Access-Control-Allow-Headers "Content-Type, Authorization";

        if ($request_method = OPTIONS) {
            return 204;
        }
    }
}
  • 允许浏览器跨域访问

  • 不转发请求

2.反向代理

server 复制代码
    listen 80;

    location /api/ {
        proxy_pass http://backend-server;
    }
}

注意:前端调用API的baseURL必须和前端静项目域名同源

相关推荐
审小匠OpenCPAi1 分钟前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution615 分钟前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
腻害兔21 分钟前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail29 分钟前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端
AI多Agent协作实战派1 小时前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
2601_955760072 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby2 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
触底反弹2 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
耳东小鹿4 小时前
对象常用方法
前端
程序员海军4 小时前
一个 AI 应用开发程序员的一天,都在屏幕前忙些什么?
前端·后端·程序员