游览器跨域问题详解

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必须和前端静项目域名同源

相关推荐
程序员黑豆5 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC5 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea5 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望6 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少6 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0076 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis7 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝8 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
计算机魔术师8 小时前
新兴多智能体系统的模式与问题
前端
用户059540174469 小时前
AI Agent 上下文污染踩坑实录:用 pytest + Redis 揪出 3 类记忆串号 bug,排查 6 小时
前端·css