前端开发服务器中的 Proxy 代理跨域实现原理解读

Posted 桃小瑞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端开发服务器中的 Proxy 代理跨域实现原理解读相关的知识,希望对你有一定的参考价值。

各位朋友你们好,我是桃小瑞,微信公众 @ 桃小瑞。在这给大家拜个晚年,祝各位朋友新年快乐。

前言

在前端的开发过程中,尤其是在浏览器环境下,跨域是个绕不开的话题,相信每个前端都会涉及到这个问题,记住的就直接手敲解决跨域问题,记不住的就只能问度娘了。😂😂

即将登场的是我们的二号人物,跨域。👇👇👇

跨域

一、什么是跨域?

跨域是指在浏览器环境中存在的一种资源同源保护策略。当页面使用ajax/fetch进行网络请求或者页面进行资源请求时,网络协议域名端口不一致时就会触发浏览器的同源策略保护机制。

浏览器就会在控制台输出像下面图片中的内容。

二、解决跨域有哪些途径呢?

见招拆招,有限制就有对策。目前有很多可以解决跨域的问题,各位看官请移步往下看👇👇👇

常见的解决跨域方式

1、 JSONP

利用script标签没有跨域的限制,从而实现跨域。

注:JSONP仅支持get请求,并且需要后端的支持。

2、 CROS( Cross-Origin Resource Sharing )

利用 CROS实现跨域,后端在请求的响应请求头上添加Access-Control-Allow-Origin属性,并设置指定的站点值,或者设置为*

注:需要前后端同时支持。

3、 nignx

nignx 反向代理

4、websocket

利用websocket,实现浏览器与服务器的全双工通信,同时允许跨域通讯。

5、iframe

iframe 搭配 document.domainlocation.hashwindow.name三种方式实现跨域。

6、node作为中间件代理

启用一个本地的node服务器充当中间件,进行跨域处理。

工作中常常用方式

在工作中常见的跨域使用方式有nignx 反向代理CROSnode 中间代理

为什么说node 中间代理也是常用的方式呢?都没看见使用过呀。来来来,此时此刻就需要涉及到我们今天的主人公了。

三、跨域疑问

跨域的时候,请求是否是发出去了的呢?数据我们是否又收到了呢?

答案:

跨域的时候,请求是已经发出去了,而且后端已经将数据返给我们了的,只是被浏览器劫持了,我们拿不到而已。

相信你看完下面的模拟对话就能懂了。

  • 前端:发送请求给后端。
  • 后端:收到请求,数据返给你了。
  • 浏览器:你后端这所在地(指:协议、域名、端口)和我所在地不对呀,肯定不可信,拦截掉,为了不让前端云里雾里的,我给它报个异常吧。
  • 我们的数据就这样被浏览器所拦截,不给我们了。

node 中间代理

node 中间代理 它还有另外一个名字,叫 Proxy 代理跨域。主角闪亮登场。👏👏

简单使用

我们一起来回顾一下它的写法:

server: 
    proxy: 
      '/api': 
        target: 'http://locahost:3000', // 目标地址
        changeOrigin: true, // 是否换源, true 换源
        rewrite: (path) => path.replace(/^\\/api/, ''), // 替换
      
    
  

环境说明

我这里使用的环境为:

  • vue
  • vite

其他的脚手架等原理都差不多。环境对我们来说都不是事,因为我们需要扒的是它的原理。

现在我们步入正题。

复现

我们现在来启动我们的项目。

pnpm run dev

我们发现,vite 给我们启动了一个本地的 node 服务器,地址为:http://127.0.0.1:5173/。

然后现在我们来发个请求试试。

我们先把 vite.config.js中的代理关掉。

我们在onMounted中添加请求。

fetch('http://127.0.0.1:5888/api', 
    method: 'get'
)

此刻我们打开我们的控制台,惊喜来了。

开启代理

我们现在放开vite.config.js中的代理注释。

再来看看

原理解析

在 vite 启动的时候,创建了一个开发服务器,然后根据我们进行的开发服务器配置进行 node 中间件代理。vite 根据配置和我们请求的 api 地址去请求对应的 api地址,我们怎么把参数给它的,它就怎么给目标地址;然后目标地址怎么给 vite 的,vite 就原模原样的给我们。可能我说的有点绕,我们一起看一下下面的图。

下图为 node 开发服务 代理请求流程图。

为什么 node 就可以解决跨域呢?

因为 node 不是运行在浏览器中的东西,所以没有跨域这种问题。

温馨提醒

跨域,也就是同源策略只存在于浏览器环境。如:chrome、ie、浏览器、webview、使用了浏览器内核的环境。在app、小程序等平台中是没有这个的。

总结

以上就是前端 Proxy 代理跨域实现原理解读的全部内容。希望本篇文章对你有所帮助。

如有不足或你有其他的见解欢迎留在评论区。

说说webpack proxy工作原理?为啥能解决跨域

参考技术A

webpack proxy ,即 webpack 提供的代理服务

基本行为就是接收客户端发送的请求后转发给其他服务器

其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制)

想要实现代理首先需要一个中间服务器, webpack 中提供服务器的工具为 webpack-dev-server

webpack-dev-server 是 webpack 官方推出的一款开发工具,将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在了一起

目的是为了提高开发者日常的开发效率, 只适用在开发阶段

关于配置方面,在 webpack 配置对象属性中通过 devServer 属性提供,如下:

devServetr 里面 proxy 则是关于代理的配置,该属性为对象的形式,对象中每一个属性就是一个代理的规则匹配

属性的名称是需要被代理的请求路径前缀,一般为了辨别都会设置前缀为 /api ,值为对应的代理匹配规则,对应如下:

proxy 工作原理实质上是利用 http-proxy-middleware 这个 http 代理中间件,实现请求转发给其他服务器

举个例子:

在开发阶段,本地地址为 http://localhost:3000 ,该浏览器发送一个前缀带有 /api 标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中

在开发阶段, webpack-dev-server 会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在 localhost 的一个端口上,而后端服务又是运行在另外一个地址上

所以在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题

通过设置 webpack proxy 实现代理请求后,相当于浏览器与服务端中添加一个代理者

当本地发送请求的时候,代理服务器响应该请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地

在代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常接收数据

注意: 服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制

以上是关于前端开发服务器中的 Proxy 代理跨域实现原理解读的主要内容,如果未能解决你的问题,请参考以下文章

前端开发:深入使用proxy代理解决跨域问题

用webpack-dev-server开发时代理,决解开发时跨域问题

vue 前端设置跨域多代理

Webpack 配置 proxy 代理解决跨域问题

Vue配置代理 解决跨域

前端跨域解决 (vscode live server proxy 代理)