本文详解 webpack proxy 解决前端跨域的原理与配置方法。通过配置 devServer.proxy,利用 webpack-dev-server 作为中间代理服务器,将本地请求转发至后端目标地址。文章涵盖 proxy 对象属性说明、http-proxy-middleware 工作原理及 Vue CLI 实战配置示例,帮助开发者在开发阶段高效解决同源策略限制。
webpack proxy 如何解决跨域问题

一、基本概念
webpack proxy,即 webpack 提供的代理服务
其基本行为是接收客户端发送的请求,并将其转发给其他服务器
主要目的是便于开发者在开发模式下解决跨域问题(由浏览器安全策略限制)
要实现代理功能,首先需要一个中间服务器,webpack 中提供服务器的工具为 webpack-dev-server
webpack-dev-server
webpack-dev-server 是 webpack 官方推出的一款开发工具,将自动编译、自动刷新浏览器等一系列对开发友好的功能全部集成在一起
其目的是为了提高开发者日常的开发效率,仅适用于开发阶段
关于配置方面,在 webpack 配置对象属性中通过 devServer 属性提供,如下所示:
// ./webpack.config.js
const path = require('path')
module.exports = {
// ...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
proxy: {
'/api': {
target: 'https://api.github.com'
}
}
// ...
}
}
devServetr 里面的 proxy 则是关于代理的配置,该属性为对象形式,对象中每一个属性就是一个代理的规则匹配
属性的名称是需要被代理的请求路径前缀,一般为了辨别都会设置前缀为 /api,值为对应的代理匹配规则,对应如下:
- target:表示代理到的目标地址
- pathRewrite:默认情况下,/api-hy 也会被写入到 URL 中,如果希望删除,可以使用 pathRewrite
- secure:默认情况下不接收转发到 https 的服务器,如果希望支持,可以设置为 false
- changeOrigin:表示是否更新代理后请求的 headers 中 host 地址
二、工作原理
proxy 工作原理实质上是利用 http-proxy-middleware 这个 http 代理中间件,实现请求转发给其他服务器
举个例子:
在开发阶段,本地地址为 http://localhost:3000,该浏览器发送一个前缀带有 /api 标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
三、跨域处理机制
在开发阶段,webpack-dev-server 会启动一个本地开发服务器,所以应用在开发阶段是独立运行在 localhost 的一个端口上,而后端服务又是运行在另外一个地址上
因此在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题
通过设置 webpack proxy 实现代理请求后,相当于浏览器与服务端中添加了一个代理者
当本地发送请求时,代理服务器响应该请求,并将请求转发到目标服务器;目标服务器响应数据后再将数据返回给代理服务器,最终由代理服务器将数据响应给本地

在代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常接收数据
注意:服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制
参考文献
https://webpack.docschina.org/configuration/dev-server/#devserverproxy
使用 webpack 的 proxy 来解决跨域
使用 webpack 的 proxy 来解决跨域问题
什么是跨域
出于浏览器的同源策略限制。同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
解决思路
使用前端服务 IP 和端口来访问后端接口地址,然后通过 webpack 的代理,访问实际的接口地址。就是遵守浏览器的游戏规则。
注意点:
axios 的 base_url 一定是自己本地的,可以不写,默认就是当前服务地址。
target 是后端的接口地址,也就是说我们在 vue.confjg.js 里面的 taget 写的是实际的请求地址。
可以使用 webpack_proxy 来解决跨域(主要说的是这里)
vue.config.js
const {defineConfig} = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
proxy: {
"/api": {
target: process.env.VUE_APP_BASE_URL, // todo 请注意,这里是后端的地址,这里不是本地的!!!!
ws: false, // websocket
secure: false, // 是否支持https
changeOrigin: true, // 是否跨域
}
}
}
})
.env.development
env="development"
VUE_APP_BASE_URL = "http://localhost:8000"
Api.ts
/*
@description:
@auther: alex
@data: 12/23/22
*/
import axios, {AxiosResponse} from "axios";
// const instance = axios({
// method: "post",
// baseURL: "", // 因为要启用代理,所以所以这里可以不用写,默认为当前服务的IP和端口
// timeout: 10000,
// })
const instance = axios.create({
method: "post",
baseURL: "",
timeout: 10000,
})
export const post = (url: string, params: any): Promise<AxiosResponse> => {
return instance.post(url, params)
}
export const get = (url: string, params: any): Promise<AxiosResponse> => {
return instance.get(url, params)
}
到此这篇关于 webpack proxy 如何解决跨域?的文章就介绍到这了,更多相关 webpack proxy 解决跨域内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!