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

跨域问题--在webpack配置文件中配置代理后为什么就能解决跨域?

跨域问题,作为前端开发者来看就是很平常的问题,通常的解决方案就是在webpack或者vite配置文件中配置一下,跨域问题就能轻松解决,那么你有没有想过为什么会出现跨域问题呢,为什么在webpack或者vite配置文件中配置一下,跨域问题就能轻松解决呢?这背后的原理是什么呢?下面就讲讲我对跨域的理解.

带着以下问题,来学习跨域吧!

  • 什么是跨域?
  • 什么是同源策略?
  • 跨域的有哪些解决方法?
  • node在跨域中扮演什么角色?
  • webpack配置文件中配置跨域代理背后的原理

1. 跨域

跨域(Cross-Origin) 指的是一个Web应用(运行在一个“源”上)试图去请求另一个“源”的资源。这个行为违反了浏览器的同源策略(Same-Origin Policy),因此会被浏览器阻止。

ajax请求时,浏览器要求当前网页和sever必须同源(安全)

这里要强调的一点是:是我能发送请求。但是我的数据回不来(服务端是返回了数据的),但是因为受到【同源策略】限制的原因,浏览器(ajax引擎)将我的响应拦截了,所以我拿不到数据.

2. 同源策略

同源:协议(例如: http, https)、域名 (例如: www.example.com, localhost)、端口 (例如: 80, 443, 8080),三者必须一致

例如:

我的地址是http://127.0.0.1:8080/index.html

要请求的URL:

https://127.0.0.1:8080/index.html 不同源,应为协议不一样

http://www.example.com:8080/index.html 不同源,应为域名不一样

http://127.0.0.1:8081/index.html 不同源,应为端口不一样

http://127.0.0.1:8081/aa/bb 同源,应为协议 域名 端口都一样

2.1 为什么需要同源策略

当然是为了安全! 这是一个至关重要的安全机制。

没有同源策略会非常危险。想象一下:

  • 你刚在 https://your-bank.com 登录了你的网银。

  • 然后你不小心访问了一个恶意网站 http://evil-site.com。

  • 如果没有同源策略,evil-site.com 的脚本就可以随意向 your-bank.com 发起请求。因为你的浏览器还带着网银的登录凭证(Cookies),它就能冒充你的身份,获取你的余额、进行转账等操作。

同源策略就像是你家小区的门禁卡系统。A小区的住户(同源)可以自由进出A小区,但不能用A小区的门禁卡进入B小区(不同源),这样就保证了各个小区的安全。

2.2 哪些操作会受到同源策略的限制

主要是那些可能读取或操作其他源数据的交互性行为:

*Ajax / Fetch 请求:最常见的情况。你不能用 JavaScript 直接通过 XMLHttpRequestFetch API 从一个不同源的服务器获取数据。

  • Web SocketServer-Sent Events 请求。

  • 读取不同源的 Cookie、LocalStorage、IndexedDB

  • 操作不同源的 DOM(例如通过 iframe 嵌入的页面)。

2.3 哪些操作不受同源策略的限制 (可以跨域)

有一些资源的嵌入是允许的,因为这是Web开放性的基础,但这些嵌入的资源不能被当前页面的JavaScript读取内容:

  1. <img src="..."> (图片)
  2. <link rel="stylesheet" href="..."> (CSS)
  3. <script src="..."> (脚本)
  4. <iframe src="...">(虽然能嵌入,但父页面无法操作其内容)

3. 跨域的有哪些解决方法

既然跨域是浏览器的行为,那么解决方案就是“说服”浏览器允许这次请求

  1. CORS (跨域资源共享) - 最正统的方案
  • 这是后端的解决方案。
  • 后端服务器在响应头中设置一系列以 "access-control-allow-origin": "*", 开头的字段(例如 Access-Control-Allow-Origin: https://your-site.com),告诉浏览器:“我允许这个来源的网站来请求我”。
  • 浏览器看到这个响应头后,就会放行前端应用接收到的数据
  1. JSONP

一个古老的技巧,利用 <script> 标签不受同源策略限制的特性来实现跨域。只能发起 GET 请求,且不安全,现在基本已被 CORS 取代。

jsonp 实现:

在前端提前定义好一个函数的名字,后端返回的是一个 函数名() 的代码片段,数据可以通过参数带回来,就相当于调用了前端提前定义的函数

<script>let oscript = document.createElement("script");ocscript.src = "https://localhost:8000/api/aaa?callback=jsonpCallback";document.body.appendChild(ocscript);// 后端会返回一个名字为jsonpCallback({name:'xiaoming'})的代码片段// 相当于调用jsonpCallback(data)的函数function jsonpCallback(data) {console.log(data, "==========data=========="); // {name:'xiaoming'}}
</script>
  1. 开发环境代理 (Proxy) - 最常用的开发阶段方案
  • 这是前端开发环境的解决方案,也就是你问题中提到的 Webpack 或 Vite 的做法。
  • 原理:浏览器不是有同源限制吗?那我就不直接请求后端API了。我让我的前端应用去请求我本地的开发服务器(同源),然后让本地开发服务器代为转发这个请求到真正的后端服务器。
  • 因为服务器之间的请求(Node.js发起的请求)不受浏览器同源策略的限制,所以可以成功。这样就“欺骗”了浏览器。

4. webpack配置文件中配置跨域代理背后的原理

简单来说,Webpack 配置解决跨域,并不是让浏览器取消了同源策略,而是“欺骗”了浏览器。它通过在本地启动一个代理服务器,将你的请求“转发”到目标服务器,从而避免了浏览器的跨域限制。

4.1 Webpack DevServer 的解决方案:代理 (Proxy)

Webpack 本身只是一个模块打包工具,解决跨域能力来自于它生态中的一个重要组件:webpack-dev-server

当你运行 npm run dev 或类似的开发命令时,webpack-dev-server 会启动一个本地开发服务器(通常默认在 http://localhost:8080),并同时提供静态文件服务和代理转发能力。

核心原理:绕开浏览器的同源策略

既然浏览器不允许 localhost:8080 直接请求 api.example.com,那我们就不直接请求。我们让浏览器去请求一个“看起来”是同源的地址,然后让一个中间人(代理服务器)去帮我们请求真正的目标地址。

这个过程如下图所示:

跨域1

假设你的 webpack.config.js 中有如下配置(或在 vue.config.js / webpack-dev-server 的配置中):

module.exports = {// ... 其他配置 ...devServer: {proxy: {'/api': { // 请求路径前缀:拦截所有以 `/api` 开头的请求target: 'https://api.example.com', // 这是你要代理到的真实后端服务器地址changeOrigin: true, // 关键配置:更改请求头中的OriginpathRewrite: {'^/api': '' // 重写路径:将请求路径中的 `/api` 前缀去掉}}}}
};

一次请求的详细流程:

  1. 前端代码发起请求:

你的前端代码中,你写的是:axios.get('/api/users')
此时,浏览器认为你要请求的是同源(http://localhost:8080)下的 /api/users,所以它会愉快地发出请求:http://localhost:8080/api/users。这里没有跨域问题。

  1. DevServer 代理拦截:

webpack-dev-server 一直在监听来自浏览器的请求。它根据你配置的 proxy 规则,发现这个请求的路径 (/api/users) 是以 /api 开头的,匹配上了规则。

  1. 代理服务器转发请求:

DevServer 的代理服务器会替你向真正的目标地址发起一个新的 HTTP 请求。这个请求的地址是:
target + 重写后的路径 = https://api.example.com + /users
关键点:这个请求是从你的本地 Node.js 服务(代理服务器)发出的,是服务器对服务器的请求。而服务器之间的通信不受浏览器同源策略的限制,所以不存在跨域问题。

  1. 接收响应并返回给浏览器:

代理服务器从 https://api.example.com/users 拿到响应数据后,再原封不动地返回给你的浏览器。

  1. 浏览器收到响应:

浏览器认为这个响应来自于 http://localhost:8080(它的同源服务器),所以它会愉快地接收数据,你的前端代码也就成功拿到了结果。

关键配置项:changeOrigin 的作用

这是一个非常巧妙且重要的配置。

  • 是什么:它决定了是否更改原始请求头中的 Host 和 Origin 字段。

  • 为什么需要它:有些后端服务器会校验 Origin 或 Host 头来做安全验证或虚拟主机路由。如果后端发现请求来自 localhost:8080,可能会拒绝请求。

  • 如何工作:当 changeOrigin: true 时,代理服务器在向后端发送请求时,会将请求头中的 Origin 和 Host 字段修改为 target 的值(即 api.example.com)。这样对于后端服务器来说,这个请求看起来就像是来自同一个域下的普通请求,从而避免了服务端的 CORS 校验。

  • 简单来说:它让代理请求“伪装”成同源请求,骗过后端服务器。

5. node在跨域中扮演什么角色?

webpack-dev-server 启动的本地开发服务器(包括其代理功能)就是一个由 Node.js 创建和运行的 HTTP 服务器。

  1. 本质是一个 Node.js 应用程序
  • webpack-dev-server 本身是一个 npm 包,它被安装在你项目的 node_modules 目录中。

  • 当你运行 npm run dev(或类似的命令)时,你实际上是在执行 node_modules/.bin/ 目录下的一个脚本,这个脚本会启动一个 Node.js 进程。

  • 这个 Node.js 进程会执行 webpack-dev-server 包的代码,从而创建并启动一个 HTTP 服务器。

  1. 底层依赖的 Node.js 模块

这个由 Node.js 创建的服务器,其底层通常会使用核心模块或流行的框架来处理网络请求,例如:

  • http 模块:Node.js 内置的核心模块,用于创建 HTTP 服务器和客户端。

  • express 框架:一个非常流行的、基于 Node.js 的 Web 应用框架。webpack-dev-server 的内部大量使用了 express 来搭建服务器、定义路由和中间件。

  • http-proxy-middleware:一个专门用于 Express 的代理中间件。这就是实现代理转发功能的核心库。当你配置 devServer.proxy 时,webpack-dev-server 实际上就是在内部自动为你创建并使用了这个中间件。

  1. 代理过程在 Node.js 环境中完成

让我们重温一下代理过程,这次从 Node.js 的角度看:

  • 启动:你输入 npm run dev,一个 Node.js 进程被启动,并在本地(如 localhost:8080)成功运行了一个 Express 服务器。

  • 拦截:浏览器请求 http://localhost:8080/api/users。这个请求被发送到你本地运行的 Node.js (Express) 服务器。

  • 转发:Express 服务器上的 http-proxy-middleware 中间件根据配置规则,识别出 /api 前缀。然后,它使用 Node.js 的 http 或 https 模块,以程序的方式(而非浏览器方式)向目标服务器 https://api.example.com 发起一个新的 HTTP 请求。这个动作完全发生在你的电脑后台,是服务器对服务器的通信。

  • 响应:Node.js 服务器收到 api.example.com 返回的数据。

  • 返回:Express 服务器再将这个数据作为响应,发回给浏览器。

跨域

这个微型服务器 就是 node!

http://www.sczhlp.com/news/24743/

相关文章:

  • brew安装-mac m4 homebrew
  • 独立网站做seo优化排名优化价格
  • 汕头百度网站建设求老哥给几个靠谱的网站
  • 深圳网站设计收费小红书关键词排名
  • 推广网站的几种方法怎样上百度做广告
  • wordpress和discuz对比在线seo短视频
  • 北京专业的做网站百度经验app下载
  • 网站截图环境 php站长工具友链检测
  • 上海简约网站建设公司最近的电脑培训学校
  • 网站制作 常州seo如何优化
  • WordPress主题 Slhao百度seo代理
  • 凡科建设网站别人能进去么网店推广的作用是什么
  • 广州网站建设哪家比较好苏州百度搜索排名优化
  • linux环境安装jdk - IT
  • 网站设计技术广告投放平台都有哪些
  • 中企动力免费做网站北京百度seo关键词优化
  • python django做的网站百度下载官方下载安装
  • 广州海珠做网站的公司网络推广的工作内容是什么
  • 做网站需要报备什么app引流推广软件
  • 【招聘专场】京东/滴滴/阿里等你来!覆盖电商、金融、IoT前沿业务!
  • py每日spider案例之某website之登录接口(AES+MD5)
  • 文本换行省略号代替
  • 继承导入
  • 组播搭建
  • brophp框架做网站模板网站seo优化包括哪些方面
  • 企业通讯录seo推广软件哪个好
  • wordpress vtrois宁波seo外包公司
  • 网站建设打不开云南省最新疫情情况
  • 萍缘网站建设工作色盲测试图 考驾照
  • 微信怎么导入wordpress西安做seo的公司