likes
comments
collection
share

node.js的接口编写

作者站长头像
站长
· 阅读数 15

下载express包

本地安装 express 到项目中

npm install express

npm i express

  • 项目目录名字不要取中文,也不要取express

  • 如果安装不成功:

    • 换个网络环境
    • 运行下npm cache clean -f,再重新运行下载命令试试

使用express快速创建web服务器

参考文档

在项目根目录下新建一个js文件,例如app.js,其中输入代码如下:


// 0. 导入 Express
const express = require('express')

// 1. 调用 express() 得到一个 app
//    类似于 http.createServer()
const app = express()

// 2. 设置请求对应的处理函数
//    当客户端以 GET 方法请求 / 的时候就会调用第二个参数:请求处理函数
app.get('/', (req, res) => {
  res.send('hello world')
})

// 3. 监听端口号,启动 Web 服务
app.listen(3000, () => console.log('app listening on port 3000!'))

说明:

  • app.get('/')相当于添加个事件监听:当用户以get方式求"/"时,它后面的回调函数会执行,其回调函数中的req,res与前面所学http模块保持一致。
  • res.send()是exprss框架给res对象补充提供的方法(http模块中的res是没有这个方法的),用于结束本次请求。类似的还有res.json(),res.sendFile() 。

托管静态资源-web服务器

用static中间件来托管静态资源,实现web服务器

参考文档

让用户直接访问静态资源是一个web服务器最基本的功能。


http://localhost:3000/1.png
http://localhost:3000/css/style.css
http://localhost:3000/js/index.js

例如,如上url分别是请求一张图片,一份样式文件,一份js代码。我们实现的web服务器需要能够直接返回这些文件的内容给客户端浏览器。

限制前缀


// 限制访问前缀
app.use('/public', express.static('public'))

这意味着想要访问public下的内容,必须要在请求url中加上/public

路由和接口

路由(Routing)是一组映射关系。它约定了当一个特定的 HTTP 方法(GET、POST 等)访问某个 URL(或者叫路径标识)时,服务器如何响应。

node.js的接口编写

格式


const app = express();

// 定义路由
app.METHOD(PATH, HANDLER)

其中:

示例


const express = require('express');
const app = express();
// 路由
app.get('/get', function(req, res) {
  // 处理逻辑
  res.json({ name: 'abc' });
});


app.listen('8088', () => {
  console.log('8088');
});

注意:

  • res.json()是express提供的方法。

图示

node.js的接口编写

写接口-get接口有参数

req.query属性

express框架会自动收集get方式从url地址中传递的查询字符串参数,并自动保存在req对象的query属性中。我们直接来获取即可。


app.get('/get', function(req, res) {
  // 直接返回对象
  console.log(req.query);
});

const express = require('express'); const app = express(); app.get('/get', function(req, res) { // 直接返回对象 console.log(req.query); res.send({ name: 'abc' }); }); app.listen('8088', () => { console.log('8088'); });

写接口-post接口

不带参数的post接口


const express = require('express');
const app = express();
app.post('/api/post', function(req, res) {
  // 直接返回对象
  res.send({ name: 'abc' });
});
app.listen('8088', () => {
  console.log('8088');
});

在请求头中传递参数


const express = require('express');
const app = express();
app.post('/api/post', function(req, res) {
  // 直接返回对象
  console.log(req.query);
  res.send({ name: 'abc' });
});
app.listen('8088', () => {
  console.log('8088');
});

post接口与get请求不同

表示的操作不同:get一般用来做查询,post一般用来添加;

传参不同:get的参数只能在请求行中通过查询字符串来传递, post一般是通过请求体(它也可以通过请求行来传递)来传递的。

请求体的参数格式

根据传递的参数的格式不同,分成三种情况来说

  • 传递普通键值对
  • 传递json
  • 传递form表单(涉及文件上传)

node.js的接口编写

post接口-普通键值对参数

目标

用express.urlencoded()来获取请求体的参数。

具体来说当content-type为x-www-form-urlencoded时,表示上传的普通简单键值对 。

定义后端接口


// 1. 使用中间件
app.use(express.urlencoded());

app.post("/add",function(req,res){
    //2. 可以通过req.body来获取post传递的键值对  
    res.json(req.body)

})

注意:

  • app.use(....)之后,在res.body中就会多出一个属性res.body。

postman测试

node.js的接口编写

post接口-json格式的参数

目标

使用express.json()来获取请求体中传递的json数据。

后端


app.use(express.json());
// 会自动加入req.body属性,这个属性中就包含了post请求所传入的参数

// 用来处理JSON格式的数据
app.post('/postJSON',(req,res)=>{
    // 后端收到post传参
    console.log(req.body);
    
    res.send('/postJSON')
})

在post传递参数时,如果要传入的参数比较复杂(多级嵌套),则可以使用json格式上传。


var data = {
 name:"abc",
 address:{
     "a":1,
     "b":2,
     "info":"c"
 }
}

postman操作

node.js的接口编写

post接口-form-data文件上传

multer包

Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。

涉及文件上传操作,则需要在服务器端额外使用第三方multer这个包(不属于express)来获取上传的信息。

后端

1.安装


npm install multer

2.使用


// 1. 引入包
const multer = require('multer');
// 2. 配置
const upload = multer({dest:'uploads/'}) // 上传的文件会保存在这个目录下
// uploads表示一个目录名,你也可以设置成其它的

// 3. 使用
// 这个路由使用第二个参数 .upload.single表示单文件上传, 'cover' 表示要上传的文件在本次上次数据中的键名。对应于前端页面上的:
//  <input type="file" name='cover'/>

app.post("/postfile", upload.single('cover'), function(req,res){
    // req.file 记录了文件上传的信息
    // req.body 记录了其它普通参数(非文件)的信息
    // 其它操作
})

说明:

  • 如果当前目录下没有uploads,它会自动创建uploads这个文件夹
  • upload.single只是处理了文件的上传。你仍可以通过req.body来获取其它参数

postman测试

对应postman的操作如下:

node.js的接口编写

接口传参理念

node.js的接口编写

请求报文:行,头,体

我们一般使用ajax技术请求接口,按http协议的约定,每个请求都有三个部分:

  • 请求: 保存了请求方式,地址,可以以查询字符串的格式附加小部分数据。

  • 请求:它可以附加很多信息,其中content-type用来约定请求体中保存的数据格式。

    content-type常见有三种取值:

    content-type的值表示请求体的数据格式示例
    application/x-www-form-urlencode普通键值对象a=2&c=1
    application/jsonjson对象{a:1,b:{c:1}}
    multipart/form-data上传文件file
  • 请求: 本次请求携带的参数。至于这些参数到了后端应该如何解析出来,由请求头中的content-type来决定。

传参途径

方法一:请求行。常见方式如下:

  • 使用ajax技术,通过get方式传参。
  • 在浏览器地址栏中输入接口地址并补充上查询字符串。

方法二:请求体。

  • ajax中的post, put, delete可以从请求体中进行传参。

另外,请求头中的content-type用来告之服务器应该以何种方式去解析请求体中的数据。

后端处理

接口的规则是由后端来定的,它会约定接口:名字,参数,格式,方式。

接口传参-整体示例

目录结构


-package.json
-node_modules
-public
-------index.html
-server.js

要求:

  • localhost:3000/index.html可以访问public下的index.html文件
  • 在后端实现三个接口,分别来处理在index.html中发出的post请求,注意:只需要在后端接收到参数即可,不需要完成具体的功能。

前端

用jquery的ajax来发请求


 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>Document</title>
 </head>
 <body>
     <button id="btn_keyvalue"> post-传递普通键值对</button>
     <hr/>
     <button id="btn_json"> post-传递json</button>
     <hr/>
     <form id="myform">
         <input type="text" name="title">
         <input type="file" name="cover">
     </form>
     <button id="btn_formdata">post-传递formdata</button>
     <hr/>
     <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
     <script>
       // 最普通的键值对格式
        $('#btn_keyvalue').click(function(){
           $.ajax({
                type:'post',
                url:'http://localhost:3000/post',
                data:{a:1,b:2},
                success(res){
                    console.log(res);
                }
            })
        })
        var obj = {
                    "name":"abc",
                    "address":{
                        "a":1,
                        "b":2,
                        "info":"c"
                    }
                }
        
        // 传递复杂的JSON对象数据
        $('#btn_json').click(function(){
            $.ajax({
                type:'post',
                url:'http://localhost:3000/postJSON',
                // contentType: false,
                contentType: "application/json; charset=UTF-8",
                data:JSON.stringify(obj),
                success(res){
                    console.log(res);
                }
            })
        })
       // 传formData表单数据
        $('#btn_formdata').click(function(){
            var fd = new FormData(document.getElementById('myform'));
            $.ajax({
                type:'post',
                url:'http://localhost:3000/admin/article_publish',
                contentType: false,
                processData:false,
                data:fd,
                success(res){
                    console.log(res);
                }
            })
        })
     </script>
 </body>
 </html>

后端接口

参考代码


const express = require('express')
const app = express();

app.use(express.static('public'))
// 使用包. 则在后续的post请求中
// 会自动加入req.body属性,这个属性中就包含了post请求所传入的参数
// 处理普通的键值对格式
// Content-Type: application/x-www-form-urlencoded
app.use(express.urlencoded())

// 处理JSON格式
// Content-Type: application/json;
app.use(express.json())

// 引入multer包
const multer = require('multer');

// 配置一下multer
// 如果本次post请求涉及文件上传,则上传到uploads这个文件夹下
// Content-Type: multipart/form-data;
var upload = multer({ dest: 'uploads/' })

// formDate
app.post('/admin/article_publish',upload.single('cover'),(req,res)=>{
    
    //upload.single('cover')
    // 这里的cover就是在页面中表单元素中的name
    // <input type="file" name="cover" />
    // 把要上传文件放在指定的目录
    console.log(req.file);
    // 其它参数,还是在req.body中找
    console.log(req.body);

    res.json({code:200,msg:'上传成功',info:req.file.path})

    
})

// 普通post 键值对
app.post('/post',(req,res)=>{
    // 希望在后端收到post传参
    console.log(req.body);

    let obj = req.body
    obj._t = Date.now();
    
    res.json(obj)
})

// SON格式的数据
// Content-Type: application/json;
app.post('/postJSON',(req,res)=>{
    // 希望在后端收到post传参
    console.log(req.body);
    
    // res.send('/postJSON')
    res.json( req.body )
})

// 实现接口,返回所传入的参数,并附上上时间戳
app.get('/getapi',(req,res)=>{
    // 通过 req.query快速获取传入的参数
    console.log(req.query);
    let obj = req.query
    
    obj._t = Date.now(); 
    res.json( obj )
})

app.listen(3000,()=>{
    console.log('express应用在3000端口启动了'); 
})

RESTful风格的接口

是一种设计的接口的方式。RESTful设计是:

  • 通过URL设计资源。接口名一般都是名词,不包含动词。
  • 请求方式(get,post,delete,put)决定资源的操作类型

普通接口设计

  • 只用到get和post接口
  • 接口的地址一般由动词+名词构成
  • 每个接口的地址都不一样

例如:

接口名:localhost:8080/getarticle类型:get功能:获取文章信息

接口名:localhost:8080/addarticle类型:post功能:添加新文章

接口名:localhost:8080/delarticle类型:post功能:删除文章

接口名:localhost:8080/updatearticle类型:post功能:编辑文章


//------------下面是普通的api设计---------------

app.get('/getarticle',(req,res)=>{
    res.send('获取')
})

app.post('/addarticle',(req,res)=>{
    res.send('添加')
})

app.post('/delarticle',(req,res)=>{
    res.send('删除')
})
app.post('/updatearticle',(req,res)=>{
    res.send('编辑')
})