webpack-dev-server原理解析及其中跨域解决方法

webpack proxy ,就是 webpack 提供的解决跨域的方案。其基本行为是接受客户端发送的请求后转发给其他的服务器,目的是为了解决在开发模式下的跨域问题。

原理

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

如下:在开发阶段,本地地址是 Http://loaclhost:3000 , 该浏览器发送一个前缀带有 /api 标识的向服务器请求数据,但是这个服务器只是将这个请求转发给另一台服务器:

const express = require('express');
const proxy = require('http-proxy-middleware');const app = express();app.use('/api', proxy({target: 'http://www.test.org', changeOrigin: true}));
app.listen(3000);// http://localhost:3000/api/foo/bar -> http://www.test.org/api/foo/bar

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

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

在这里插入图片描述
通过设置 webpack proxy 实现代理请求后,相当于浏览器和服务器之间添加了一个代理服务器。
当本地发送请求的时候,中间服务器会接受这个情求,并将这个请求转发给目标服务器(也就是后端服务器),目标服务器返回数据后,中间服务器又会将数据返回给浏览器,当中间服务器将数据返回给服务器的时候,它们两者是同源的,并不会存在跨域的问题。

服务器和服务器之间是不会存在跨域资源的问题的。

webpack-dev-server

webpack 提供代理服务器的工具是webpack-dev-server,但只适用于开发阶段,线上要实现代理一般通过 nginx 来配置。

webpack 中的服务器工具 webpack-dev-server,实质上是启动了一个 express 服务器。

proxy 代理是利用 http-proxy-middleware 这个http代理中间件实现将请求转发给其他服务器。
(vite 是用的 http-proxy,其实 http-proxy-middleware 也是基于 http-proxy 的)

背后其实都是使用 node 来启动 server 服务器,这也是为什么我们常说这种代理只能在开发阶段使用,因为 build 生产包时我们并不会打包一个 node 服务器进去,线上要实现代理一般直接通过 nginx 来配置。

可以在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'}}// ...}
}

在这里插入图片描述

webpack-dev-server常用的配置项

Proxy代理

它的目的是设置代理来解决跨域访问的问题。举例:
我们的一个api请求地址(也就是服务器地址)是 http://localhost:8888
但是本地启动服务器的域名是 http://localhost:8000
这个时候发送网络请求就会出现跨域的问题(端口不同)。
所以将请求先发送到一个代理服务器,代理服务器和API服务器没有跨域的问题,就可以解决我们的跨域问题了。


module.exports = {//...devServer: {proxy: {'/api': {// 以 /api 开头的请求,会转发到下面的 target 配置target: 'http://localhost:8888',// 目标服务器pathRewrite: { "^/api": "", // 重写路径为空,即请求路径中没有/api字符串"^/api": "/abcd" // 重写路径为abcd,即将请求路径中的/api字符串替换成/abcd},secure: false,// https接口,需要配置这个参数changeOrigin: true,// 将请求头中的host 配置为 target},},host: '0.0.0.0', //用于指定devDerve使用的host,如果你希望服务器外部可以访问,设定如 host: '0.0.0.0'https: true, // 默认情况下dev-server使用http协议,通过配置可以支持https,// 注意:默认使用自签名证书,也可以配置自己的证书// https: {//     ca: './path/to/server.pem',//     pfx: './path/to/server.pfx',//     key: './path/to/server.key',//     cert: './path/to/server.crt',//     passphrase: 'webpack-dev-server',//     requestCert: true,// },// 开启热模块替换hot: true,},
};
  • target:表示的是代理到的目标地址(也就是要访问的服务器地址),比如 /api会被代理到 http://localhost:8888/api
  • pathRewrite:默认情况下,我们的 /api 也会被写入到URL中,即:http://localhost:8888/api, 如果希望删除,可以使用pathRewrite比如:
    配置成 "^/api": "",那么/api/user => http://localhost:8888/user,地址中没有/api,因为重新路径是空的;
    配置成"^/api": "/abcd" ,那么/api/user => http://localhost:8888/abcd/user,即将请求路径中的/api字符串替换成/abcd
  • secure: 默认情况下,不接受在 HTTPS 上运行且证书无效的后端服务器。 https接口,需要配置这个参数为false;
  • changeOrigin:它表示是否更新代理后请求的headers中host地址,一般设置为true

proxy配置中 changeOrigin: true,// 将请求头中的host 配置为 target。
那为什么要更改请求头中的host呢?

因为一台服务器上可以部署多个项目,当我们发送请求时,DNS 会将域名解析为 IP 地址,此时,也就确定了我们目标服务器,那如何确定我们要访问的是哪个项目呢?这就需要用到 host 字段了。

请求头中Host用来指定请求的 域名/ip地址和端口号,通常用于指定服务器的地址,端口号可以省略,省略时默认为80端口。

此时我们将host指定为a.com就会访问到淘宝服务了。
在这里插入图片描述
所以如果一台服务器上部署多个项目时,我们需要更改请求头中的host,来指定我们要访问的项目。

一台服务器只有一个项目时,我们可以不用更改请求头中的host,因为DNS解析后,就确定了我们要访问的项目。

但为了以后用起来方便,就统一将这个配置项changeOrigin设置为true。

host

devServer.host 配置项⽤于配置 DevServer 服务监听的地址,默认使⽤ 8080 端⼝。 如果 8080 端⼝ 已经被其它程序占有就使⽤ 8081,如果 8081 还是被占⽤就使⽤ 8082,以此类推

例如:
你想要局域⽹中的其它设备访问你本地的服务,可以在启动 DevServer 时带上 --host 0.0.0.0
也可以在webpack配置项devServer.host中设置0.0.0.0
host 的默认值是 127.0.0.1 即只有本地可以访问 DevServer 的 HTTP 服务。

localhost 和 0.0.0.0 的区别:

  • localhost:本质上是一个域名,通常情况下会被解析成127.0.0.1。
  • 127.0.0.1:回环地址(Loop Back Address),表达的意思其实是我们主机自己发出去的包,直接被自己接收。

正常的数据库包经过 应用层 - 传输层 - 网络层 - 数据链路层 - 物理层 ,而回环地址,是在网络层直接就被获取到了,是不会经过数据链路层和物理层的。

比如:
我们监听 127.0.0.1时,在同一个网段下的主机中,通过ip地址是不能访问的。
0.0.0.0:监听IPV4上所有的地址,再根据端口找到不同的应用程序,比如我们监听 0.0.0.0时,在同一个网段下的主机中,通过ip地址是可以访问的

port、open、compress

devServer.port设置监听的端口,默认情况下是8080,不能设置为null,可以设置自动为auto

module.exports = {//...devServer: {port: 8080, },
};

devServer.open告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true 以打开你的默认浏览器。

module.exports = {//...devServer: {open: true,//在浏览器中打开指定页面:open: ['/my-page']//提供要使用的浏览器名称,而不是默认名称// open: {//   app: {//  name: 'google-chrome',//  },// },},
};

devServer.compress告诉 dev-server 在服务器端启用 gzip 压缩,用于减少服务器向前端传输的数据量,提高浏览的速度。

module.exports = {//...devServer: {compress: true,},
};

在这里插入图片描述
参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

专门为机器学习开发的jpy语言

这本来是一个为工科教学专门开发的附属品,并不是说Python或Java有多不好,根本上它就是一个Java工程教材,但又要结合人工智能。因此,出现了这样一个包容性的怪胎,可以用python一样的语法与Java一起编写。 没流行起来的一…

<信息安全>《2 国内主要企业网络安全公司概览(二)》

4 北京天融信科技有限公司(简称天融信) 信息内容LOGO成立日期创始于1995年总部北京市海淀区上地东路1号院3号楼北侧301室背景民营企业是否上市天融信[002212]A股市值99亿主要产品网络安全大数据云服务员工规模6000多人简介天融信科技集团(证券代码:0022…

【开源】基于JAVA的停车场收费系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 停车位模块2.2 车辆模块2.3 停车收费模块2.4 IC卡模块2.5 IC卡挂失模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 停车场表3.2.2 车辆表3.2.3 停车收费表3.2.4 IC 卡表3.2.5 IC 卡挂失表 四、系统实现五、核心代码…

在达沃斯,人工智能引发的乐观情绪可谓一分为二

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

基于STM32的基础实验(一)

LED实验 采用STM32单片机设计电路,控制LED灯的亮灭,对单片机端口的位操作进行演示。 实验需要: STM32核心板独立LED 电路原理图 LED灯实际上是一个特殊的二极管,通过控制高低电平亮灭。如图所示,当1为低电平&#…

数据可视化 | 期末复习 | 补档

文章目录 📚介绍可视化🐇什么是可视化🐇科学可视化,信息可视化,可视分析系统三者之间有什么区别🔥🐇可视化的基本流程🐇可视化的两个基本设计原则🐇数据属性&#x1f407…

数学建模学习笔记||层次分析法

评价类问题 解决评价类问题首先需要想到一下三个问题 我们评价的目标是什么我们为了达到这个目标有哪几种可行方案评价的准则或者说指标是什么 对于以上三个问题,我们可以根据题目中的背景材料,常识以及网上收集到的参考资料进行结合,从而筛…

GEE:最小距离分类器(minimumDistance)分类教程(样本制作、特征添加、训练、精度、最优参数、统计面积)

作者:CSDN @ _养乐多_ 本文将介绍在Google Earth Engine (GEE)平台上进行最小距离分类(minimumDistance)的方法和代码,其中包括制作样本点教程(本地、在线和本地在线混合制作样本点,合并样本点等),加入特征变量(各种指数、纹理特征、时间序列特征、物候特征等),运行…

本地git切换地区后,无法使用ssh访问github 22端口解决方案

问题 由于放假回家,发现之前一直使用正常的git,与github无法通讯,pull和push都无法连接。报错如下: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 原因 可能是所…

docker常用基础命令

文章目录 1、Docker 环境信息命令1.1、docker info1.2、docker version 2、系统日志信息常用命令2.1、docker events2.2、docker logs2.3、docker history 3、容器的生命周期管理命令3.1、docker create3.2、docker run 总结 1、Docker 环境信息命令 1.1、docker info 显示 D…

Linux 命令大全 CentOS常用运维命令

文章目录 1、Linux 目录结构2、解释目录3、命令详解3.1、shutdown命令3.1、文件目录管理命令ls 命令cd 命令pwd 命令tree 命令mkdir 命令touch 命令cat 命令cp 命令more 命令less 命令head 命令mv 命令rm 命令ln 命令tail 命令cut命令 3.2、用户管理useradd/userdel 命令用户的…

使用残差网络识别手写数字及MNIST 数据集介绍

MNIST 数据集已经是一个几乎每个初学者都会接触的数据集, 很多实验、很多模型都会以MNIST 数据集作为训练对象, 不过有些人可能对它还不是很了解, 那么今天我们一起来学习一下MNIST 数据集。 1.MNIST 介绍 MNIST 数据集来自美国国家标准与技术研究所, National Institute of S…

2. SpringBoot3 实战之用户模块接口开发

文章目录 开发模式和环境搭建开发模式环境搭建 1. 用户注册1.1 注册接口基本代码编写1.2 注册接口参数校验 2. 用户登录2.1 登录接口基本代码编写2.2 登录认证2.2.1 登录认证引入2.2.2 JWT 简介2.2.3 登录功能集成 JWT2.2.4 拦截器 3. 获取用户详细信息3.1 获取用户详细信息基本…

openEuler安装KVM

1、关闭防火墙和selinux [rootlocalhost ~]# systemctl stop firewalld[rootlocalhost ~]# setenforce 0 2、下载软件包 libvirt:用于管理虚拟化平台的开源的 API,后台程序和管理工具。 qemu:开源(模拟)软件&#…

【MySQL】InnoDB 什么情况下会产生死锁

🍎个人博客:个人主页 🏆个人专栏:数据库 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 结语 我的其他博客 前言 在数据库管理系统中,特别是使用 InnoDB 存储引擎的 MySQL 中,死锁是一个可能影响…

Win10下在Qt项目中配置SQlite3环境

资源下载 官网资源:SQLite Download Page 1、sqlite.h sqlite-amalgamation-3450000.zip (2.60 MiB) 2、sqlite3.def,sqlite3.dll sqlite-dll-win-x64-3450000.zip (1.25 MiB) 3、 win10下安装sqlite3所需要文件 sqlite-tools-win-x64-3450000.zipht…

万界星空科技MES系统的生产管理流程

对于生产型工厂来说,车间生产流程无疑是最重要的管理环节,繁琐的生产细节让企业很难找到合理的生产管理方法,导致人工效率低、错误多、成本高。如果想要解决这些问题,工厂就必须要有一套自己的生产管理系统,这样才能提…

【Leetcode】410. 分割数组的最大值

文章目录 题目思路1.max_element2.partial_sum3.upper_bound4.distance 代码运行结果 题目 题目链接 给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k 个非空的连续子数组。 设计一个算法使得这 k 个子数组各自和的最大值最小。 示例1&#xff1…

玩转 SpEL 表达式

本文概览 欢迎阅读本文,其中我们将深入探讨 Spring Expression Language(SpEL)的语法和实际应用。从基础概念到高级用法,我们将在本文中了解如何使用 SpEL 提高代码的灵活性和表达力。无论大家是初学者还是有经验的开发者&#x…

ACM题解Day2|1.台风, 2.式神考试,3.DNA,4.方程求解

学习目标: 博主介绍: 27dCnc 专题 : 数据结构帮助小白快速入门 👍👍👍👍👍👍👍👍👍👍👍👍 ☆*: .。. o(≧▽≦)…