点击上方蓝字“大前端技术沙龙”关注我

您的关注意义重大

原创@大前端技术沙龙

最近同事小G总是闷闷不乐,让我感觉慌慌的,难道是我平时压榨小G了?我转念一想,不应该啊,工作量事先都评估好了,没道理天天加班啊。

坐下来聊聊后,小G向我吐槽说,”改bug效率太低了,每天加班改bug,都不能早点下班陪女神!”

我深吸一口气,“卧槽,忘记传授小G秘籍了...”

在一步步提问引导下,我搞清楚了小G的问题所在......

问题引入

相信很多前端朋友在线上debug时都吐槽过npm run devnpm start太费时的问题吧(这里提到的两条npm脚本代指启动前端dev server)。

由于环境差异,开发环境和生产环境下,我们访问的后端服务域名是不一样的。那么当我们debug生产问题时,难免还是要修改下webpack devServerproxy配置指向生产环境域名,然后重启devServer,这个过程一般比较缓慢。

有些时候可能测试环境也能复现bug,那么只要接入测试环境也能排查问题原因。但这不是本文关注的重点,本文主要说说如何提高debug效率。

webpack-dev-server反向代理

0202年了,如果作为开发者的你还不了解反向代理,那么是很有必要去关注下了。

我们知道,跨域对于前端而言是一个无法逃避的问题。如果不想在开发时麻烦后端同事,前端仔必须通过自己的手段解决跨域问题。当然,你帮后端同事买包辣条,他给你通过CORS解决跨域也是可以的。

还好,webpack-dev-server帮我们解决了这个痛点,它基于Node代理中间件http-proxy-middleware实现。

配置起来也非常简单:

proxy: {// 需要代理的url规则"/api": {target: "https://dev.xxx.tech", // 反向代理的目标服务changeOrigin: true, // 开启后会虚拟一个请求头OriginpathRewrite: {"^/api": "" // 重写url,一般都用得到}}
}

这个时候小G打断了我,表示不理解。

反向代理是个什么意思呢?举个例子,我想找马云借钱,马云是肯定不会借给我的。

但是我有一个好朋友老张,我于是找老张借了1W块,但是我没想到这个朋友和马云关系不错,他从马云那里借了1W块,然后转给我。也就是说,我不知道我借到的钱实际来源于哪里,我只知道我从我朋友老张那里借到了钱,老张给我做了一层反向代理。

具体到开发中就是,我前端仔要从https://dev.xxx.tech这个域名调用后端接口,但是我前端开发服务运行在http://localhost:8080,直接调用后端接口会跨域,被浏览器同源策略阻塞,所以这条路是走不通的。

因此我需要从前端服务器做个代理,这样我就可以用http://localhost:8080/api/user/login这种形式调用接口,就好像在调前端自己的接口一样(因为我访问的是前端的url嘛)。

然而实际上是前端服务器做了一层代理,把http://localhost:8080/api/user/login这个接口代理到https://dev.xxx.tech/user/login。这对前端开发者而言是无感的。

简单总结就是:反向代理隐藏了真实的服务端;相反地,正向代理隐藏了真实的客户端,类似kexueshangwang这种。

debug痛点

问题来了,假设我们正在feature分支开发需求,这个时候上头通知要即时排查和解决一个生产bug,假设生产环境域名为https://production.xxx.tech

我们一般会stash代码,然后切fix分支,修改target的值为"https://production.xxx.tech",然后重新运行npm start重启开发服务器接入生产环境,静静等待,放空自己......

这个时候我们就会幻想“唉,要是不用等这么久就好了!”

是的,其实很多时候,一个bug并不复杂,可能解决bug只要1分钟,然而我们切换环境重新运行开发服务器就花了1分钟(大多数情况可能超过这个时间)。那么如何解决这个问题?

代理层解耦

是的,有的同学已经想到了,只要把代理服务器抽离出来,问题便可以得到解决,我不再需要把前端编译过程和服务代理目标捆绑在一起。在生产环境,这种Nginx转发对大多数人而言早已是熟门熟路,然而很少有人会尝试在开发环境中也这么做。那么不妨这样试试呢!

下载Nginx

我们照常下载Nginx,选择Windows稳定版即可。

固定前端代理

为了避免在debug线上问题时需要切换proxy target而重新运行npm start,我们在前端层把proxy target固定下来。比如我固定访问127.0.0.1:8090(当然,实际上访问哪个端口可以视个人情况调整)。

proxy: {"/api": {target: "127.0.0.1:8090", // 固定代理目标changeOrigin: true,pathRewrite: {"^/api": ""}}
}

然后从127.0.0.1:8090肯定是无法访问到后端接口的,请接着往下看!

Nginx代理

由于前端的接口访问已经固定为127.0.0.1:8090,那么剩下的工作就交给Nginx吧。我们只要在Nginx中监听本地8090端口,把请求统统转发给目标服务器即可,配置如下:

server {listen       8090;server_name  127.0.0.1;location / {proxy_pass https://dev.xxx.tech;proxy_http_version 1.1;proxy_set_header   Upgrade          $http_upgrade;proxy_set_header   Connection       "upgrade";proxy_set_header   Host             $host;# proxy_set_header   X-Real-IP        $remote_addr;proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;}
}

可以看到,我在配置中注释了X-Real-IP,而我们在生产环境下配置Nginx时,一般会保留这几项Host,X-Real-IP,X-Forwarded-For,用以保留请求的服务器域名,原始客户端和代理服务器的IP等信息。

如果不注释X-Real-IP,前端访问入口的真实IP是127.0.0.1localhost,Nginx不认可这样的本地ip,直接返回404,客户端请求不予代理到其他远程服务器。不扯了,这里具体的原因我也不知,如有大佬知道原因,还请点拨下,太感谢了。

好了,回到正题,有了以上的配置,我们就可以将前端代理层和Nginx代理层解耦,前端固定通过本地127.0.0.1:8090访问后端接口,而具体接口是代理到开发环境、测试环境或是生产环境,由Nginx决定,只需要修改nginx.conf后重启即可。

而Nginx热重启是非常快的,一条命令即可实现,几乎零等待时间。

// windows下是这个命令
nginx.exe -s reload
// linux是这样的
nginx -s reload

本地域名

听到这里,小G又将了我一军。

还好我早有准备,没有自乱阵脚。

如果真的遇到本地端口被占用的情况,最简单的办法当然是换个端口。

为了杜绝这种情况,我们可以引入本地域名,兼具“装逼”效果。

我们知道,域名是通过解析后才能得到真实的服务IP。而域名解析过程中也有这么一些关键节点,是我们应该知道的。

  • 浏览器缓存

  • 操作系统hosts文件

  • Local DNS

  • Root DNS

  • gTLD Server

借用网上一张图说明下大致流程(侵删)。

上图没提到hosts文件,但是不影响我们魔改。我们只要在操作系统hosts文件这个节点动下手脚,就可以实现本地域名了。

首先,我们找到C:\Windows\System32\drivers\etc\hosts这个文件,打开后在最后新增一条解析记录

127.0.0.1 www.devtest.com

然后保存这个文件,保存hosts文件时需要administrator权限。

这就相当于告诉本地操作系统,如果用户访问www.devtest.com,我就给他解析到127.0.0.1这个ip

所以,我们在Nginx只要监听127.0.0.180端口即可,配置如下。

server {listen       80;server_name  127.0.0.1;location / {proxy_pass https://dev.xxx.tech;proxy_http_version 1.1;proxy_set_header   Upgrade          $http_upgrade;proxy_set_header   Connection       "upgrade";proxy_set_header   Host             $host;proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;}
}

最后,我们只要在前端工程中把代理目标设置为www.devtest.com即可。

proxy: {"/api": {target: "http://www.devtest.com", // 固定代理目标changeOrigin: true,pathRewrite: {"^/api": ""}}
}

这样前端访问的某接口http://localhost:8080/api/user/login就会被代理到http://www.devtest.com/user/login,而www.devtest.com被本地hosts文件解析到127.0.0.1,接着Nginx监听了127.0.0.180端口,将请求转发到真实的后端服务,完美!

对了,www.devtest.com是我特意命名的一个无法访问的域名,所以你千万别把www.taobao.com这种地址解析到本地哦,不然你没法给女神买礼物别怪我。。。

今天分享给大家的干货就这么多,祝愿大家准点下班陪女神!

看到最后,求个关注点赞,欢迎大家加我微信交流技术,闲聊也可以哦!

 爱心三连击

1. 如果您觉得这篇文章质量还不错,请滑动至下方,点击在看,或者点击右上角选择分享给朋友或分享到朋友圈。

2. 长按下方二维码识别并关注公众号,您的鼓励意义重大。

3. 进入公众号,在对话框内回复“加群”,进入技术交流群,一起交流学习成长。

转发和在看   是最大的鼓励

「前端必看」这篇Nginx反向代理技巧,助你准时下班陪女神相关推荐

  1. 「入门运维必看」一篇让小白彻底搞懂性能调优!

    前言: 什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么人来进行性能调优?(who) 怎么样进行性能调优?( ...

  2. 「面试必背」Tomcat面试题(收藏)

    「面试必背」Tomcat面试题(建议收藏) 2022-04-27 16:31·java柚子茶 前言 在工作中,作为 Java 开发的程序员,Tomcat 服务器是大家常用的,也是很多公司现在正在用的. ...

  3. 「前端组件化」该怎么理解?

    大家好,我是若川.今天分享一篇关于「前端组件化」的好文.欢迎点击下方卡片关注我. 以下是正文~ 这里我们一起来学习前端组件化的知识,而组件化在前端架构里面是最重要的一个部分. 讲到前端架构,其实前端架 ...

  4. 人工智能必看的 45 篇论文(附下载地址)

    点击上方"小詹学Python",选择"星标"公众号 重磅干货,第一时间送达 [导读]今天介绍下做人工智能必看的45篇论文,并附上下载地址,以及一本提到这45篇论 ...

  5. 关于 ChatGPT 必看的 10 篇论文

    目录 1 Transformer 2 GPT-3 3 InstructGPT 4 Sparrow 5 RLHF 6 TAMER 7 PPO 8 In-Context Learning 8.1 Why ...

  6. 使用nginx负载均衡的webservice wsdl访问不到_谁说前端不用懂,Nginx 反向代理与负载均衡(超实用)...

    谁说前端不需要懂-Nginx反向代理与负载均衡 学到老活到老 前端圈一直很新,一直要不停的学习,而且在进入大厂的路上,还要求熟悉一门后台语言等等.用一句别人开玩笑的话来说,java十年前的技术现在还能 ...

  7. nginx解决浏览器跨域问题_前端通过Nginx反向代理解决跨域问题

    在前面写的一篇文章SpringMVC解决跨域问题,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式: JSONP CORS WebSocket 可是这几种方式 ...

  8. sql server代理无法启动_谁说前端不需要懂Nginx反向代理与负载均衡

    作者 | chenhongdong 链接 | https://juejin.im/post/5b01336af265da0b8a67e5c9 学到老活到老 前端圈一直很新,一直要不停的学习,而且在进入 ...

  9. 前端跨域,nginx反向代理的解决方案

    前端跨域,nginx反向代理的解决方案 参考文章: (1)前端跨域,nginx反向代理的解决方案 (2)https://www.cnblogs.com/Yukiyi/p/7912223.html (3 ...

最新文章

  1. BCH两周年独立日已至,世界各地爱好者纷纷举办Meetup庆祝
  2. GitHub 近 100,000 程序员“起义”:向“996”开炮!
  3. Java-Web机试练习题一、后台管理系统——管理员管理模块
  4. c语言hash存储,C语言实现HashTable(一) 介绍
  5. Hibernate 发展之路
  6. nutch,hbase,zookeeper兼容性问题
  7. MySQL 删除存储过程
  8. ES6学习(七)—Set 和 Map 数据结构
  9. npm 安装出错 npm ERR! request to https://registry.npmjs.org/express failed, reason: unable to verify th
  10. 机械设计二级减速器设计
  11. cobar mysql_阿里开源Mysql分布式中间件:Cobar
  12. SIM868获取NTP时间
  13. 40种顶级思维模型,学会任何1种都让你受用无穷,赶紧点赞收藏
  14. 服务假死问题解决过程实记(一)——问题发现篇
  15. java基础回顾之Map中 TreeMap排序原理-二叉树
  16. Win11 PE下如何快速设置IP如何新建共享文件夹并设置为everyone完全控制权限
  17. AAAI 2020使用深度强化学习的MOBA游戏《Towards Playing Full MOBA Games with Deep Reinforcement Learning》打败王者荣耀顶尖选手
  18. Speedoffice(word)如何调整页眉位置
  19. RFID仓储物流托盘管理解决方案
  20. 晶创电梯卡的数据结构

热门文章

  1. Blender基础:曲线倒角
  2. Linux(CentOS)下的apache服务器配置与管理
  3. java读取excel的maven_JAVA如何读取Excel数据
  4. 数据挖掘公开课推荐(含下载链接)
  5. 使用 HtmlUnit 操作网页(登录58同城)
  6. 微型计算机测控系统课程设计报告,微机控制课程设计报告电阻加热炉温度控制系统设计.doc...
  7. java计算机毕业设计铝塑门窗的研制和生产管理源代码+数据库+系统+lw文档
  8. 电子信息计算机方向可以调剂到哪些专业,电子信息工程专业的领域和考研方向...
  9. 又是模型评估?到底怎么评估?『附 AUC 评估的三计算方法』
  10. iphone实况照片导出_如何使用iPhone拍摄真棒实况照片