node.js的接口编写
下载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(或者叫路径标识)时,服务器如何响应。
格式
const app = express();
// 定义路由
app.METHOD(PATH, HANDLER)
其中:
-
app
是 express 实例 。(const app = express()) -
METHOD
是一个 HTTP 请求方法。 全小写格式。如:post,get,delete等。 -
PATH
是请求路径(相当于在http模块中用到过的url.parse(req.url).pathname
)浏览器url 服务端路径 http://localhost:8080 / http://localhost:8080/public/a/index.html /public/a/index.html http://localhost:8080/index.html?a=1&b=2 /index.html -
HANDLER
是当路由匹配到时需要执行的处理函数。(req,res)=>{ }
示例
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提供的方法。
图示
写接口-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表单(涉及文件上传)
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测试
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操作
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的操作如下:
接口传参理念
请求报文:行,头,体
我们一般使用ajax技术请求接口,按http协议的约定,每个请求都有三个部分:
-
请求行: 保存了请求方式,地址,可以以查询字符串的格式附加小部分数据。
-
请求头:它可以附加很多信息,其中content-type用来约定请求体中保存的数据格式。
content-type常见有三种取值:
content-type的值 表示请求体的数据格式 示例 application/x-www-form-urlencode 普通键值对象 a=2&c=1 application/json json对象 {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('编辑')
})
转载自:https://juejin.cn/post/7008080861283221518