当前位置:   article > 正文

基于宝塔面板和Node.JS开发简单的API接口_nodejs制作api

nodejs制作api

为什么写这篇博客?

我是一名大学生,出于对互联网世界的好奇,在网上收集了各种信息资料,尝试过 N 种方法,在搭建服务器这方面也遇到很多问题,不过还好,经历过重重问题的考验,最终还是找到了通过最简单的方法搭建一个API接口的方法,所以想写下这篇博客。一是为了记录我的搭建经历;二是跟大家分享一下我搭建的一个经过,希望我的经历能帮助到大家,让对这方面有兴趣的人少走些弯路。如有什么不足的地方也还请大家帮忙指出,也希望大佬互喷!

这个页面解决什么问题?

这篇文章将通过 Node.JS 搭建一个简单的API接口,以满足在后续开发中对数据的一个存储需求!
PS:因为个人对数据内容的需求量不大,所以并没有涉及到数据库的来进行数据保存!

我需要掌握什么前置知识?

理论上,只要读者具有使用搜索引擎查找问题的能力,以及足够细心和耐心,照着教程一字一句地看,一步步地做,那么读者不需要任何前置知识。
当然,最基本的电脑维护操作,如对Windows系统的一些基本概念、,至少读者是要会的。

我需要准备什么?

搭建网站环境最基本要求是这样的:
1 、服务器(Windows Server系统)(我以华为云的服务器为例,配置:2H4G 3M)
2 、联网的台式/笔记本电脑(用于调试以及配置服务器以及代码)

PS:服务器并不是必需品,也可以在自己电脑中搭建Web服务环境,然后搭建API服务,具体的搭建步骤可以参考这篇文章

准备就绪!

让我们首先来浏览一遍简明版的搭建流程,以便你时刻知道自己走到了哪一步,该干什么:

1 、开放服务器的端口
2 、安装宝塔面板,配置Web服务环境
3 、安装 Node.JS,进行项目初始化
4 、通过Node.JS配置 JavaScript 脚本运行环境
5 、配置接口处理事件(核心)
  • 了解Node.js的基本概念和语法
  • 了解Express框架的基本概念和使用
  • 设计API接口的URL和参数
  • 编写API接口处理函数
  • 通过CORS策略解决浏览器的跨域机制
  • 编写中间件处理请求参数(如body-parser等)
6 、启动API服务
7 、客户端请求测试
8 、停止API服务
9 、资源素材下载(附)

PS:如果你是有经验的电脑玩家,那么你可以不需要借助下面的文章,直接根据上面的简明摘要,开始配置了。

Step 1 . 开放服务器的端口

我以华为云的 HECS(云耀云服务器) 为例:

1 、打开 华为云 - 控制台 ,找到所购买的服务器。
2 、打开华为云服务器的安全组配置界面:
在这里插入图片描述
3 、开放以下端口(8888 、888 、80 、21 、20)以及一个自定义端口(12345)。
在这里插入图片描述
在这里插入图片描述

Step 2 . 安装宝塔面板,配置Web服务环境

1 、打开 宝塔面板官网 ,下载 Windows Server 版的安装程序,解压后进行安装!

2 、宝塔面板安装完成之后,首次进入会弹出登录配置界面,如下:(附:面板使用教程
在这里插入图片描述
3 、打开面板,通过账号密码首次登录面板之后,选择适合自己的套件(根据服务器的性能决定),然后选择 “一键安装” ,等待安装完成!
在这里插入图片描述
4 、安装完成之后,选择 “ 网站 ” ,然后删除自动生成的站点,创建新的站点
在这里插入图片描述
5 、打开浏览器,在URL地址栏输入 服务器的公网IP 进行查询,如果效果如下,则表示Web服务环境搭建完成!
在这里插入图片描述
End:到此,宝塔面板服务搭建完成!

Step 3 . 安装 Node.JS,进行项目初始化

1 、进入Node.JS官网,下载对应的Node.JS版本进行安装( 我以 Node.JS - v18.16.0 版本为例 )(附:Node.JS历史版本
2 、通过命令 node -v检查 Node.JS 是否安装成功!
3 、通过命令 npm -v检查npm是否安装成功!
在这里插入图片描述> 4 、在【资源管理器】中找到宝塔面板搭建的Web服务存放的文件路径。并在地址栏输入“CMD”,然后回车,打开DOS命令窗口。
在这里插入图片描述
3 、输入命令 npm init -y 初始化项目。命令执行玩之后,可以看到,会生成一个名为“package.json”的配置文件
在这里插入图片描述
4 、基于自己的需求,对多余的文件进行删除或保留!
在这里插入图片描述
End:到此,API项目的初始化就已经完成!

Step 4 . 通过Node.JS配置 JavaScript 脚本运行环境

1 、通过 NPM 安装以下三个 Node.JS 第三方模块(以下为局部安装命令):
a)、Express 模块 - 安装命令:npm install express
b)、Nodemon 模块 - 安装命令:npm install nodemon
c)、CORS 模块 - 安装命令:npm install cors
在这里插入图片描述
2 、全局安装(进行局部安装之后,全局安装即可省略!):
全局安装(express + nodemon )- 安装命令:npm install express nodemon -g
在这里插入图片描述
执行完成之后,会看到与 package.json 文件同级的目录下,会多出一个 node_modules 的文件夹,里面存放的是Node.JS第三方模块的依赖资源。

End:到此,所有的环境就已经配置完成!

Step 5 . 配置接口处理事件(核心)

PS:由于个人对接口的需求不一样,所以在这我就通过一段代码演示一些基础的功能!具体的需求还得自己去学习贯通,不过其基本语法使用的还是JavaScript,对于前端开发者来说学习成本还是比较低的!

服务器端 - 处理服务(实例代码比较简单,展示的都是一些比较常用的方法,具体的使用场景以及需求得根据实际情况进行开发):

1 、在与package.json文件同级的目录下创建一个JavaScript文件,如(Server.js),代码内容如下:

const express = require("express");        // 引入Express框架

const path = require("path")    // 引入path模块

const fs = require("fs")        // 引入fs模块

// const cors = require("cors")        // 引入cors模块

const http = require('http');

const querystring = require('querystring'); // 引入Node.js内置的querystring模块

const bodyParser = require("body-parser");   // 引入body-parser模块

const { json } = require("body-parser");
const { send } = require("process");
const { url } = require("inspector");

let app = express();    // 项目的顶级对象

const PORT = 12345;      // 设置API调用的接口

// 两个配置项,bodyParser功能添加到app项目中
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


// 添加 CORS 头部信息,解决跨域问题
app.use(function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

/* -------------------------- “/” - 接口配置 - GET -------------------------- */
// 【GET 请求】app.get(可以处理的请求路径,处理函数);
// 【执行条件】当浏览器访问这个路径的时候,这个函数就会执行
app.get("/", (req, res) => {
  let client = {
    // 记录当前时间  
    Time : new Date().getFullYear() + "-" + (new Date().getMonth() + 1) + "-" + new Date().getDate() + " " + new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds(),
    // 记录发送请求的客户端 IP 地址  
    ClientIP : req.connection.remoteAddress.replace('::ffff:', ''),
    // 记录Get请求的查询值
    QueryValue : req.query,
    // 记录设备的详细信息  
    ClientDevice_Detail : req.headers['user-agent'],
    // 记录简要设备信息  
    ClientDevice_Easy : /\(([^)]+)\)/.exec(req.headers['user-agent'])[1]
  };

  // 服务器端 - 请求信息提醒
  console.log(`${client.Time} 】 终端 (IP:${client.ClientIP} )通过“/”向服务器发送了GET请求!(设备:${client.ClientDevice_Easy}`);

  res.send(client); // 返回数据给请求终端  
});


/* -------------------------- “/” - 接口配置 - POST -------------------------- */
// 【POST 请求】app.post(可以处理的请求路径,处理函数);
// 【执行条件】当浏览器访问这个路径的时候,这个函数就会执行
app.post("/", (req, res) => {

  // 服务器 - 请求信息提醒!
  console.log(`${new Date().getFullYear()}-${new Date().getMonth() + 1}-${new Date().getDate()}  ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()} 】 终端 (IP:${req.connection.remoteAddress.replace('::ffff:','')} )通过“/”向服务器发送了POST请求!`);

  let ClientText = req.body;    // 获取客户端发送过来的数据

  // 拼接目标文件路径
  let filePath = path.join(__dirname, "DataFile", "Data.json");
  // 获取目标文件内容
  let TextContent = fs.readFileSync(filePath, "utf8")

  let TempObj = JSON.parse(TextContent);    // 转换数据类型 ( String -> Obj )

  TempObj.Previous = TempObj.Record;    // 覆盖原来的记录
  TempObj.Record = ClientText.Text          // 新增记录

  // 将新数据重新写入文件
  fs.writeFileSync(filePath,JSON.stringify(TempObj))

  res.send(TempObj)   // 返回数据给请求端
})


/* -------------------------- “/Demo” - 接口配置 - GET -------------------------- */
// 【GET 请求】app.get(可以处理的请求路径,处理函数);
// 【执行条件】当浏览器访问这个路径的时候,这个函数就会执行
app.get("/Demo", (req, res) => {
  
  // 服务器 - 请求信息提醒!
  console.log(`${new Date().getFullYear()}-${new Date().getMonth() + 1}-${new Date().getDate()}  ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()} 】 终端 (IP:${req.connection.remoteAddress.replace('::ffff:','')} )通过“/Demo”向服务器发送了Get请求!`);

  res.send(`【/Demo】API接口 - 数据调用成功!`); // 返回数据给请求终端  
});


// 启动端口监听
app.listen(PORT, () => {
  console.log(`---------------------- API 服务已启动,正在监听 ${PORT} 端口 ---------------------- `);
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

2 、目录结构:
在这里插入图片描述


Step 6 . 启动API服务

在DOS命令窗口输入以下任一命令,启动服务,开始监听指定端口!

node Server.js  // 启动端口监听,一次性服务
nodemon Server.js 	// 启动端口监听,会自动检测服务器文件是否更新,并进行服务器重启!
  • 1
  • 2

End:到此,API接口的配置就结束了 ,接下来是测试接口的环节!

Step 7 . 客户端请求测试

客户端 - API请求实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>API - Test</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
    <h1>华为云 - 云耀云服务器</h1>
    <button id="Btn_Get">【jQuery】API 测试 - Get请求</button>
    <button id="Btn_Post">【jQuery】API 测试 - Post请求</button>
    <br><br>
    <button id="Ajax_Get">【Ajax】API 测试 - Get请求</button>
    <button id="Ajax_Post">【Ajax】API 测试 - Post请求</button>
    <br><br>
    <button id="SecondAPI">"/Demo"入口 - jQuery的GET请求</button>
    <br><br>
    <button id="CompressionTest">-------- 服务器 - 抗压测试 -------- </button>
    <pre id="show">代码展示,等待获取中…………</pre>
    <script>
        // 【jQuery】向服务器发送GET请求
        Btn_Get.onclick = function(){
            $.ajax({
                url: 'http://…………:12345',
                method: 'GET',
                data: {Title: 'Hello!', Text: "你好!"},
                success: function(response) {
                    console.log('请求成功', response);
                    document.querySelector("#show").innerHTML = JSON.stringify(response, null, 4);
                },
                error: function(error) {
                    console.log('请求出错', error);
                    document.querySelector("#show").innerHTML = "GET - 请求失败!";
                }
            });
        }

        // 【jQuery】向服务器发送POST请求
        Btn_Post.onclick = function(){
            let Text = window.prompt("请输入新记录的值 :")
            $.ajax({
                url: 'http://…………:12345',
                method: 'POST',
                data: {name: '温Wen', Text: Text},
                success: function(response) {
                    console.log('请求成功', response);
                    document.querySelector("#show").innerHTML = JSON.stringify(response, null, 4);
                },
                error: function(error) {
                    console.log('请求出错', error);
                    document.querySelector("#show").innerHTML = "POST - 请求失败!";
                }
            });
        }

        // 【Ajax】- Get请求
        Ajax_Get.onclick = function(){
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://…………:12345?Title=Hello!&Text=你好,我是温先森!');
            xhr.onload = function() {
                if (xhr.status === 200) {
                    console.log('请求成功', xhr.response);
                    document.querySelector("#show").innerHTML = JSON.stringify(JSON.parse(xhr.response),null,4);
                } else {
                    console.log('请求出错');
                    document.querySelector("#show").innerHTML = "GET - 请求失败!";
                }
            };
            xhr.onerror = function() {
                console.log('请求出错');
                document.querySelector("#show").innerHTML = "GET - 请求失败!";
            };
            xhr.send();
        }

        // 【Ajax】- Post请求
        Ajax_Post.onclick = function(){
            let Text = window.prompt("请输入新记录的值:");
            let xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://…………:12345', true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.onreadystatechange = function() {
                if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
                    console.log('请求成功', this.responseText);
                    document.querySelector("#show").innerHTML = JSON.stringify(JSON.parse(this.responseText), null, 4);
                } else if (this.readyState === XMLHttpRequest.DONE) {
                    console.log('请求出错');
                    document.querySelector("#show").innerHTML = "POST - 请求失败!";
                }
            };
            xhr.onerror = function() {
                console.log('请求出错');
                document.querySelector("#show").innerHTML = "POST - 请求失败!";
            };
            xhr.send('name=温Wen&Text='+encodeURIComponent(Text));
        }

        // "/Demo"入口 - jQuery的GET请求
        SecondAPI.onclick = function(){
            $.ajax({
                url: 'http://…………:12345/Demo',
                method: 'GET',
                data: {Title: 'Hello!', Text: "你好!"},
                success: function(response) {
                    console.log('请求成功', response);
                    document.querySelector("#show").innerHTML = JSON.stringify(response, null, 4);
                },
                error: function(error) {
                    console.log('请求出错', error);
                    document.querySelector("#show").innerHTML = "GET - 请求失败!";
                }
            });
        }


        // 服务器 - 抗压测试
        CompressionTest.onclick = function(){
            var count = 0;
            for(let i = 0 ; i < 100 ; i++ ){
                document.querySelector("#show").innerHTML = `${count++}`;
                $.ajax({
                    url: 'http://110.41.0.15:12345/',
                    method: 'GET',
                    async: true, // 将 async 设置为 false
                    success: function(response) {
                        console.log('请求成功', response);
                        document.querySelector("#show").innerHTML = response;
                    },
                    error: function(error) {
                        console.log('请求出错', error);
                        document.querySelector("#show").innerHTML = "GET - 请求失败!";
                    }
                });
            }
            document.querySelector("#CompressionTest").innerHTML = ` - - - - - 测试结束 - - - - - `;  
        }
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140

请求结果示例:
在这里插入图片描述

Step 8 . 停止API服务

在正在运行API接口的DOS命令窗口输入【快捷键】 Ctrl + C,即可终止运行!

在这里插入图片描述

Step 9 . 资源素材下载(附)

1 、服务器端 & 客户端请求测试 - 源码下载:点击下载(蓝奏云)

相关答疑

Question 1 . 可以选择哪些端口号作为我服务器的端口

在使用Node.js搭建API服务时,端口号的选择范围是从0到65535。然而,在实际应用中,常用的端口号范围是1024到49151之间。这是因为0到1023之间的端口号通常被系统保留用于特定的服务,而49152到65535之间的端口号归类为动态或私有端口,可以用于自定义应用程序。所以在选择端口号时,最好避开这些保留端口和常用端口,以免与现有服务冲突。通常推荐选择大于1024且未被占用的端口号

Question 2 . 为什么配置好宝塔面板,在浏览器 通过服务器公网 IP 地址进行访问会显示 Nigex 服务?

因为自动生成的站点域名填写的不对,需要修改成自己服务器的公网IP ,或者把自动生成的站点 删掉,自己建一个新的站点。

Question 3 . 有其他测试接口的方法吗 ?

有,不一定得根据第7步进行测试,还可以使用Postman工具进行测试,但是得注意跨域问题,在使用Postman工具进行测试的时候,不会出现跨域问题,测试环境比较理想!。

Question 4 . 什么是跨域?

Web 浏览器遵循同源策略(Same-Origin Policy),该策略要求不同源(即协议、域名、端口号有且只有一个不同)的网页之间默认不能相互访问彼此的资源。这是为了保护用户的安全和隐私。
简单点说就是在浏览器中,当一个网页的 JavaScript 代码向另一个域名的资源发送请求时,如果这个请求的目标域名与当前网页的域名不同,就会出现跨域问题

Question 5 . 有哪些办法能解决跨域问题?

有以下几种方法可以解决跨域问题:

  1. JSONP(JSON with Padding):JSONP 是一种利用 <script> 标签可以跨域加载资源的特性来实现跨域请求的方法。通过在请求中指定回调函数名,服务器返回的数据会被包裹在该函数调用中,从而可以在客户端通过回调函数来获取数据。
  2. CORS(Cross-Origin Resource Sharing):CORS 是一种现代化的跨域解决方案,通过在服务器端设置特定的响应头,允许浏览器跨域访问指定的资源。通常需要在服务器端设置 Access-Control-Allow-Origin 头部字段来指定允许访问的来源域名。
  3. 代理服务器:可以通过在自己的服务器上设置一个代理服务器,将跨域请求转发到目标服务器上。客户端只需要与自己的服务器进行通信,而不直接与目标服务器进行跨域请求,从而规避了同源策略的限制。
  4. Nginx反向代理:可以通过配置Nginx服务器作为反向代理,在同一个域名下,不同路径下的请求转发到不同的目标服务器上,实现跨域请求。
  5. WebSocket协议:WebSocket 是一种全双工通信协议,它支持跨域通信。通过在服务器端进行设置,可以允许浏览器与其他域的 WebSocket 服务器进行跨域通信。

我希望…………

如果大家都看到了这里,我能够向大家要个赞吗,你们的点赞是我最大的动力!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/68998
推荐阅读
相关标签
  

闽ICP备14008679号