游览器跨域问题详解

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

相关推荐
SameX1 小时前
后台 GPS 记录从半天掉电 30% 到全天 8%,我的三版方案演进
前端
Cder1 小时前
用 React + Ink 在终端里「优雅搜索」:开源 CLI 设计与非交互模式实践
前端·agent
像我这样帅的人丶你还1 小时前
前端监控体系与实践(二):全局监控
前端·javascript·vue.js
颜酱1 小时前
LLM为核,上下文为限:拆解AI Agent生态的底层逻辑
前端·人工智能
前端那点事1 小时前
Vue3 超全复盘!30+前端高频核心知识点(开发+面试全覆盖)
前端·vue.js
幼儿园技术家2 小时前
为什么 SSR 一定会有 hydration mismatch?
前端
FlyWIHTSKY2 小时前
Vue 3 中 RouteRecord 详解(Vue Router 4)
前端·javascript·vue.js
yingyima2 小时前
用 cron 定时发送邮件报告:实战案例详解
前端
GAMC2 小时前
从 “凭感觉写代码” 到 “按规范做开发”:OpenSpec 让 AI 编程回归工程化
前端·人工智能