web项目的编写过程当中,常常会出现前后端进度不一致的情况,就像谈恋爱的两个人如果步调不一致,那么肯定会很累,更有甚者因节奏的不一样导致分手的下场,所以为了避免前后端走到“分手”的这一步,我们需要把前后端解耦开来,可是对于前端来说,你让我自己写假数据行啊,可是模拟不到网络请求这一步,那这个mock的假数据真是“食之无味,弃之可惜”,于是,

Node: "对面的女孩看过来,看过来,看过来~这里的哥哥有点帅"

node挺身而出,帮我们用三两句话就搭建起了一个代理服务器,于是乎,前端:“面包(数据)我有了,阳光(网络请求)我有了,你(后端)最后来给我爱情就好~”,啊,说了一堆废话,还是来看看我们的可切换源数据的代理node服务器是长啥样吧~~

/*** @author luojun <https://github.com/Luooojunnn>* @desc 本中间服务器可以切换数据源,如需二次改造,请github上提问
*/
const http = require('http')
const url = require('url')
const path = require('path')
const fs = require('fs')
const colors = require('colors')/*** 环境判断
*/
const ENV = process.argv[2] && process.argv[2].split('=')[1]http.createServer((req, res) => {try {/*** 将读取api文件写在服务程序内,实现动态更新* 遇到一个坑,就是node跑在gw根目录导致这里读取文件采用相对路径就会读不到东西*/let apiFile = JSON.parse(fs.readFileSync(`${path.join(__dirname, '../../data/apiManage.json')}`))if (url.parse(req.url).pathname !== '/favicon.ico') {// 判断请求方式,请求参数let reqMethod = req.method === 'GET' ? 'GET' : (req.method === 'POST' ? 'POST' : req.method)// 寻址回值if (apiFile[url.parse(req.url, true).pathname.substring(1)]) {res.setHeader('Access-Control-Allow-Origin', '*')res.setHeader('Allow', '*')res.setHeader('Access-Control-Allow-Headers', '*')if (reqMethod === 'OPTIONS') {res.end('')}// 根据环境变量选择接口let apiAdress = apiFile[url.parse(req.url, true).pathname.substring(1)][ENV]// TODO 根据环境判断是够需要一个代理转发if (ENV === 'dev') {console.log('在dev环境'.red)// 保存请求参数,用于转发let paramsData = ''if (reqMethod === 'GET') {paramsData = url.parse(req.url, true).search} else if (reqMethod === 'POST') {let res = ''req.on('data', (reqData) => {res += reqData})req.on('end', (reqData) => {paramsData = resconsole.log(paramsData)})}console.log(`接口名 ${url.parse(req.url, true).pathname},采用 ${reqMethod} 请求方式,传递的参数是 ${paramsData}`)let finalAddress = path.join(__dirname, '../../data/', apiAdress)// dev环境 - 读取接口,输出jsonlet apiData = fs.readFileSync(finalAddress)res.end(apiData.toString('utf8'))} else {console.log('在测试环境'.red)// online环境 - 代理转发 PS: hostname 不含协议let hn = url.parse(apiAdress).hostnamelet pt = url.parse(apiAdress).pathreq.headers.host = hn //url.parse(apiAdress).hostlet sRes = resif (reqMethod === 'GET') {if (url.parse(req.url, true).search) {pt = '' + pt + url.parse(req.url, true).search}console.log(`接口名 ${url.parse(req.url, true).pathname},采用 ${reqMethod} 请求方式,传递的参数是 ${url.parse(req.url, true).search}`)HCLIENTFC({hostname: hn + '',path: pt + '',method: reqMethod + '',headers: req.headers}, (data, statusCode, header) => {sRes.writeHead(Number(statusCode), header)sRes.end(data)}, '')} else if (reqMethod === 'POST') {let res = ''req.on('data', (reqData) => {res += reqData})req.on('end', (reqData) => {console.log(`接口名 ${url.parse(req.url, true).pathname},采用 ${reqMethod} 请求方式,传递的参数是 ${res}`)/*** 将 host 头部信息改成online的域名信息,否则host会指向代码里的请求的localhost:9000* !!! 为什么一定要用 header ,因为可以在做爬虫的时候,冒充浏览器端,越过有些代码的机器人识别* */HCLIENTFC({hostname: hn + '',path: pt + '',method: reqMethod + '',headers: req.headers}, (data, statusCode, header) => {sRes.writeHead(Number(statusCode), header)sRes.end(data)}, res)})}}} else {res.writeHead(404)res.end('')}}} catch (e) {res.end('接口解析出现了一些错误...')throw new Error(e)}
}).listen(9000, 'localhost', () => {console.log('接口服务启动在localhost:9000')
})/*** online服务器* @param {Object} obj - 需要参入的配置参数* @param {string} obj.hostname - 目标地址ip或域名* @param {string} obj.path - 请求路径 (这里忘写导致出问题)* @param {string} obj.method - 请求方法* @param {Object} obj.headers - 请求头* @param {function} callback - 回调* @param {string} params - 转发参数
*/
function HCLIENTFC ({ hostname, path = '/', method = 'GET', headers }, callback = () => { }, v = '') {let resData = ''console.log('接口的信息参数:========1'.blue)console.log('hostname:' + hostname)console.log('path:' + path)console.log('method:' + method)console.log(headers)console.log('post发送的数据v:' + v)console.log('接口的信息参数:--------2'.blue)/*** 由于发送了header,其accept接受的数据类型可能和返回的数据类型不一致,所以可能导致接口超时,必要时,可去掉发送header*/const HCLIENT = http.request({hostname,path,method,headers}, (res) => {res.setEncoding('utf8')res.on('data', (chunk) => {resData += chunk})res.on('end', () => {console.log('接口返回结果是:', resData.toString())console.log('测试环境返回状态码:', res.statusCode)console.log('测试环境返回响应头:', res.headers)callback(resData, res.statusCode, res.headers)})})HCLIENT.on('error', (e) => {console.log('出现错误,错误信息为:' + e)return resData})HCLIENT.write(v)HCLIENT.end()
}复制代码

node:"阳光大熊货前来报到!!"

有啥不清楚的可以留言大家一起讨论,共同学习进步!!sir!

git地址:一些好玩的Node

PS: 之前关于get、post请求参数的获取判断有误,线已改正(180927)

转载于:https://juejin.im/post/5ba51f8e5188256bab295bf3

node搭建的一个应用在前端项目中的可切换接口的代理服务器相关推荐

  1. 如何快速了解一个新的前端项目?

    在接受一个新的项目后,要想快速了解它,就需要一种抽象思维进行剥茧抽丝,遵守项目搭建的基本规律,犹如庖丁解牛,游刃有余. 以达到可能给快速跟上团队成员的节奏进行开发.下面我就给大家总结一下,拿到一个新的 ...

  2. axios 使用步骤很简单,首先在前端项目中,引入 axios:

    2019独角兽企业重金招聘Python工程师标准>>> 前端网络访问,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,网络访问较多的采用 vue-resources ...

  3. php项目前端src文件结构,前端项目中目录结构优化的方法总结

    本篇文章给大家带来的内容是关于前端项目中目录结构优化的方法总结,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 目录结构优化 现在前端项目越来越变得像大型工程了,而且越来越复杂了,需要 ...

  4. 前端项目中使用js-beautify格式化、美化js代码

    前端项目中使用js-beautify格式化.美化js代码 1.js-beautify介绍 很多网站的js,html,css代码做了混淆处理,导致难以阅读,这个时候js-beautify工具就可以派上用 ...

  5. 前端项目中使用百度地图api,含实例

    前言 一.使用百度地图接口的步骤 二.简单例子 1.第一个地图 2.控件 3.静态/动态添加点圈线面 4.文字标注.信息窗口 5. Web服务API-IP定位服务 6.Web服务API-地点检索服务 ...

  6. 主数据项目中的历史数据切换方案

    前言:主数据项目中的历史数据切换方案需要结合应用演进策略和业务给出的切换需求,出具对应的切换方案. 历史数据切换注意点: 一.选择整体切换原则 需根据实际业务情况,制定历史数据切换原则 切换原则介绍 ...

  7. 前端项目中的CI/CD实践(自动化部署)

    前言 前置知识 Linux Docker Nginx Github 可以干嘛 作为一套面向开发和运维团队的解决方案,CI/CD 主要解决集成新代码和向用户频繁交付应用的问题. 更直接地说,就是可以解放 ...

  8. 前端项目中常用的工具包(拖拽排序表格、打印导出表格、文本复制等)【持续更新~~~】

    表格类: cdn库 cdn vxe-table[开源的多功能表格] 简介 一个基于 vue 的 PC 端表格组件,支持增删改查.虚拟滚动.懒加载.快捷菜单.数据校验.树形结构.打印导出.表单渲染.数据 ...

  9. 前端项目中使用excel等office办公软件

    如何在项目中读取office --- excel.doc.ppt文件 废话不多说,直奔主题,为了实现这项功能,前前后后找了不少插件等等.. 1.spreadjs 纯前端表格控件,界面很高大尚,功能也很 ...

最新文章

  1. CSS Modules
  2. [ CodeVS冲杯之路 ] P1044
  3. Wireshark使用学习
  4. Oracle12g添加c##scott用户
  5. 两个数据集,本地可以关联,正式库关联不了
  6. Redis与RabbitMQ作为消息队列的比较
  7. [转]Redis集群的配置
  8. 用java写了一个汉诺塔
  9. mysql修改主键生成策略信息_常用Hibernate 主键生成策略
  10. python饼形图_Python | 饼形图
  11. C++ 工程实践(2):不要重载全局 ::operator new()
  12. linux 平台驱动分析
  13. INDEMIND荣登「AI中国」机器之心2021人工智能年度榜单
  14. 【中兴笔试题】三角形面积
  15. html td 超链接,web开发---给td添加超链接
  16. 手机sd卡恢复工具android版,手机内存卡文件恢复工具(SD卡数据恢复助手)V1.5 正式版...
  17. 惠普触控板使用指南_惠普笔记本关闭触摸板【操作思路】
  18. html css 和js共同实现手风琴
  19. java中Excel导出echart图片
  20. nacos2.0服务提示注册成功,但是服务管理列表中没有注册到

热门文章

  1. 「每周CV论文推荐」 初学深度学习人脸关键点检测必读文章
  2. 强化学习在携程酒店推荐排序中的应用探索
  3. 案例分析 | SAP如何帮助企业实现端到端的数字化供应链管理
  4. 如何从 900 万张图片中对 600 类照片进行分类? | 技术头条
  5. 解剖科大讯飞的AI“乌托邦”
  6. 学习计算机视觉你需要知道这关键的八点
  7. 英特尔联合Facebook研发AI芯片:CPU老厂能在AI时代打好翻身仗吗
  8. SAP QM 采购货物收到第三方仓库,转库回工厂仓库之后质检之处理
  9. IEEE Spectrum调查:AI 的 6 种最坏情况
  10. Nature:AI 引导人类直觉,帮助发现数学定理