您现在的位置是:群英 > 开发技术 > web开发
创建nodejs项目后如何实现前端本地开发接口代理服务
Admin发表于 2022-05-17 17:54:561215 次浏览
在实际案例的操作过程中,我们可能会遇到“创建nodejs项目后如何实现前端本地开发接口代理服务”这样的问题,那么我们该如何处理和解决这样的情况呢?这篇小编就给大家总结了一些方法,具有一定的借鉴价值,希望对大家有所帮助,接下来就让小编带领大家一起了解看看吧。

背景

我们在前端开发的接口联调阶段,经常会遇到跨域问题,因为本地通常使用localhost域名来启动项目,当然我们可以通过配置host解决这个问题,但当需要访问线上页面的时候,又必须关闭host;我们也可以通过webpack的插件dev-server来配置代理(proxy),但有时需要和多个服务端研发进行接口联调,因此就需要配置多个proxy,设置多个虚拟接口前缀,还要考虑发布后线上如何不走代理,整体来说,配置工作是比较麻烦的。

目标

针对以上背景,我们需要一个更加简单灵活的接口代理方案,我们的目标是:

  • 接入简单,只需在前端项目中增加少量代码;
  • 环境隔离,只针对本地开发环境使用代理,对线上无影像,发布时也无需修改代码;
  • 配置灵活:可针对不同接口进行差异化配置,可同时对接多个服务端研发进行联调;

方案

我们在使用webpack的插件dev-server时,本质是本地运行了一个代理服务,前端页面发送的网络请求,实际都是请求了这个代理服务,再由代理服务转发到实际的接口url上,最后代理服务再将接口返回的数据透传给前端页面。

根据这个原理,我们来自行搭建一个代理服务,也将它在本地运行,来实现同dev-server插件一样的代理过程,但我们会在本方案中引入更加灵活的一种配置方式,也就是通过修改config.json配置文件,来实现更加简化的配置,以及随用随改的灵活特性。

实施

创建nodejs项目

首先在本地创建一个nodejs项目(需要安装nodejs环境,版本建议12+),命名为api-proxy-server,具体步骤略。

温馨提示:本文的代理服务项目源代码,笔者免费提供!只需 点赞+关注 即可在评论区留言索要,留下您的邮箱,笔者会在看到的第一时间发送,项目源代码readme文件详细描述了如何使用,方便您快速接入。

编写express服务

我们的代理服务使用express框架来开发(需要安装依赖),也可以根据个人习惯使用其他框架,比如koaegg.js等。

首先在项目主文件中导入相关依赖:

const express = require('express');
const http = require('http');
const bodyparser = require('body-parser');
const app = express();

然后使用bodyparser对请求数据进行解析:

app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json());

接下来这一步很关键,就是要允许跨域,我们要允许所有域名和请求的访问,具体设置如下:

app.all('*', (req, res, next) => {
  res.header('access-control-allow-origin', req.headers.origin);
  res.header('access-control-allow-headers', 'content-type, content-length, authorization, accept, x-requested-with');
  res.header('access-control-allow-methods', 'put, post, get, delete, option');
  res.header('access-control-allow-credentials', 'true');
  res.header('x-powered-by', '3.2.1');
  next();
});

然后我们给这个服务编写默认的路由(也可以理解为接口,对于前端来说,服务端提供的路由都可以视为接口),默认的路由我们定义为get请求,方便我们在浏览器直接访问,来验证服务是否成功启动。

express挂载路由的方式如下:

app.get('/', (req, res) => {
  res.send('hello, welcome use api proxy.');
});

最后,我们来编写启动服务的代码,如下:

const port = 8080;
http.createserver(app).listen(port);
console.log(`http://127.0.0.1:${port} 服务已启动`);

按照以上步骤编写完代码后,启动服务,在浏览器中访问http://127.0.0.1:8080,如果看到浏览器显示“hello, welcome use api proxy.”说起服务启动成功了。

关于如何启动服务,笔者的做法是,在package.json中配置启动脚本dev,然后运行npm run dev即可,也可以通过pm2进程守卫插件(需要安装依赖)来启动服务,这样做的好处是可以在程序报错时,保证服务不会停止。

启动脚本配置如下:

"scripts": {
    "start": "pm2 start ./src/server.js",
    "stop": "pm2 stop ./src/server.js",
    "dev": "node ./src/server.js"
},

编写代理接口

在上述步骤中,我们已经可以启动代理服务,并编写了一个默认的get路由(接口),接下来我们来实现本文的核心内容,编写一个post类型的接口,用于对前端接口请求进行代理。

为了方便后续的维护和扩展,我们将代理接口的源代码编写到一个独立的文件中,目录为src/routes/api,文件名为index.js,然后在主文件中导入并挂载路由即可,代码如下:

const api = require('./routes/api');
// ......
app.post('/api', api);

注意:代理接口的路由我们定义为/api,因此在前端项目中调用这个服务的完整路径就是http://127.0.0.1:8080/api,这个接口只能通过axios来访问,因为它是post类型的,不支持浏览器访问验证。

我们打开src/routes/api/index.js文件来编写具体的代码,首先导出一个基本的路由函数:

const axios = require("axios");
const qs = require("qs");
const fs = require("fs");
const fspath = require("path");

module.exports = (req, res) => {
  // ......
}

在这个函数内,我们来处理前端请求,先从请求体中获取参数:

const { path, params } = req.body;

其中path指定了要访问哪个服务端接口路径,params是要透传给服务端的实际入参。

然后我们在src/routes/api/目录下,创建一个接口配置文件config.json,这个配置文件维护了默认的服务端接口域名或ip地址,以及默认的请求方式和数据类型。具体定义如下:

属性名 说明 示例
baseurl 服务端接口默认地址 http://192.168.1.17
method 请求方式,默认是post get / post
contenttype 数据类型,默认是json form / json

继续编写代码,来读取这个config.json配置文件,代码如下:

// 读取接口配置文件
const configpath = fspath.resolve(process.cwd(), './src/routes/api/config.json');
if (!fs.existssync(configpath)) {
  res.json({ code: '-1', msg: '接口配置文件不存在!' });
  return;
}
const configstr = fs.readfilesync(configpath, { encoding: 'utf-8' });
let config = null;
try {
  config = json.parse(configstr);
} catch (error) {
  res.json({ code: '-1', msg: '接口配置文件格式有误,解析失败!' });
  return;
}
// 获取接口默认配置
let { baseurl, method='post', contenttype='json', extra=[] } = config;

代码写到这里,我们已经拿到了真实的服务端接口地址、请求类型以及数据类型,然后就可以通过axios来发送请求了,但这样并不支持个别请求的差异化,比如有的接口需要跟另外的服务端研发联调,也就是baseurl不同、有的接口请求类型是get,有的接口请求的数据类型是application/x-www-form-urlencoded,因此我们需要一种机制来实现对差异化接口的配置,我们继续改写config.json文件,加入extra数组,在这个数组中,我们放入一组对象,来定义个别接口的差异化属性,具体定义如下:

属性名 说明 示例
path 接口路径(必填),需要差异化配置的接口 /user/permision
baseurl 服务端接口地址(选填) http://192.168.1.16
method 请求方式(选填) get / post
contenttype 数据类型(选填) form / json

有了以上配置,我们就可以遍历extra数组,如果当前接口请求的path在其中,就需要按照差异化的配置发送请求,具体代码如下:

// 获取额外的接口配置
if (extra.length > 0) {
  const extracfg = extra.find(item => item.path === path);
  if (extracfg) {
    baseurl = extracfg.baseurl || baseurl;
    method = extracfg.method || method;
    contenttype = extracfg.contenttype || contenttype;
  }
}

最后我们使用axios来发送请求到实际的服务端接口地址,然后将返回的数据下发给前端页面即可。代码如下:

const url = baseurl + path;
const headers = {};
if (contenttype === 'form') {
  headers['content-type'] = 'application/x-www-form-urlencoded';
}
axios({
  method,
  url,
  headers,
  timeout: 3000,
  data: contenttype === 'form' ? qs.stringify(params) : params
}).then(result => {
  res.json(result.data);
  log.api(url, params, result.data);
}).catch(error => {
  res.json({ code: '-1', msg: '网络错误' });
  log.api(url, params, '网络错误');
});

代码中的log是用来记录日志的,方便我们追踪代理服务的运行情况,具体实现可查看本项目源代码。

至此我们的代理服务就开发完成了,运行这个服务,我们就可以在前端项目中接入并使用它了。**注意:**当我们修改了config.json文件后,保存即可,不需要重启服务。如果电脑关机重启了,则需要手动启动代理服务。

前端项目接入

在前端项目封装axios请求的地方,判断如果是本地开发环境,则将url指向此服务,并对入参进行简单包装即可。由于我们只对本地环境做了接口代理,因此发布项目时无需任何修改,发布后的版本仍会调用实际的服务端接口。

代码示例:

let baseurl = 'http://api.xyz.com'; // 线上接口域名
let data = { a: 1 } // 接口入参
let path = '/user/permision'; // 实际的接口路径
let url = baseurl + path; // 请求的完整接口url

if (process.env.node_env === 'development') {
  url = 'http://127.0.0.1:8080/api';
  data = { path, params: data }
}

// 发送请求
axios({ url, data })



以上就是关于“创建nodejs项目后如何实现前端本地开发接口代理服务”的介绍了,感谢各位的阅读,希望文本对大家有所帮助。如果想要了解更多知识,欢迎关注群英网络,小编每天都会为大家更新不同的知识。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

相关信息推荐
2021-11-12 16:05:25 
摘要:这篇文章给大家分享的是laravel怎样实现异常处理为JSON。小编觉得挺实用的,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
2022-06-21 17:09:27 
摘要:本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于数据处理中常见的一些问题,包括了数据的增删改查、数据的排序、数据的去重、平级列表变成树形结构以及数组对象相同项合并处理,下面一起来看一下,希望对大家有帮助。
2022-11-19 17:51:52 
摘要:本篇文章给大家带来了关于vue的相关知识,其中主要介绍了关于$emit的相关问题,在子组件中通过$emit来调用父组件中的方法实现,下面一起来看一下,希望对大家有帮助。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部