nodejs第三方模块 express框架 托管静态资源

30 篇文章 0 订阅

express框架

一.基本介绍

  • Express 是一个基于Node.js平台,快速、开放、极简的 web 开发框架
  • web 开发: 对不同的请求能够显示页面;提供接口服务;
  • 对于node.js来说,Express是一个第三方模块,有丰富的 API 支持,强大而灵活的中间件特性
  • Express不对 Node.js 已有的特性进行二次抽象,只是在它之上扩展了 Web 应用所需的基本功能
  • 参考链接

理解:

  • 我们前面用http模块来支持web服务,写接口 ----- 原生js
  • 现在要用express来写web服务,写接口 ------ jQuery

二.运行第一个express程序

expresss是一个第三方模块(在npm上可以下载),在使用它之前要先去下载它,在下载包之前要先创建项目,并通过npm init 创建package.json文件

1. 创建项目并初始化

创建一个空目录(learn-express)(目录名不要有汉字,也不是某个包的名字),在此目录下运行npm init 命令来生成package.json文件

# 在你的项目根目录下,打开小黑窗
# 1. 初始化 package.json 文件
npm init -y

2. 下载express包

参考文档:http://expressjs.com/en/starter/installing.html

# 2. 本地安装 express 到项目中
# npm install express
npm i express

注意:

  • 项目目录名字不要取中文,也不要取express
  • 如果安装不成功:
    • 换个网络环境
    • 运行下npm cache clean -f,再重新运行下载命令试试

3. 使用express快速创建web服务器

参考文档:http://expressjs.com/en/starter/hello-world.html

在项目根目录下新建一个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()
  • express 框架会增强req,res的功能

三.托管静态资源-web服务器

参考文档:http://expressjs.com/en/starter/static-files.html

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

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

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

http模块时,我们已经实现了这些功能了,但是要写很多代码,现在使用express框架,只需一句代码就可以搞定了,这句代码是 express.static('public')

1. 忽略前缀

// 加载 Express
const express = require('express')

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

// 2. 设置请求对应的处理函数
app.use(express.static('public'))


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

此时,所有放在public下的内容可以直接访问,注意,此时在url中并不需要出现public这级目录

  • public下新建index.html,可以直接访问到。

2. 限制前缀

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

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

四.路由和接口

参考文档:http://expressjs.com/en/starter/basic-routing.html

路由(Routing)是由一个 URL(或者叫路径标识)和一个特定的HTTP 方法(GET、POST 等)组成的,涉及到应用如何处理响应客户端请求。每一个路由都可以有一个或者多个处理器函数,当匹配到路由时,这些个函数将被执行。

1. 格式

const app = express();

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

其中:

  • appexpress 实例。(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)=>{ }

2. 写get接口

1) get无参数
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提供的方法。

2) get接口有参数

express框架自动收集get方式从url地址中传递的查询字符串参数,并自动保存在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');
});

注意:

  • req.query属性是express框架额外提供的属性。

3. 写post接口

post接口与get请求不同在于:它的参数一般是通过请求体来传递的。根据传递的参数的格式不同,分成三种情况来说

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

具体来说当content-typex-www-form-urlencoded时,表示上传的普通简单键值对 。如果通过postman测试的话,对应的设置如下:
在这里插入图片描述

步骤

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

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

})

注意:

  • app.use(....)之后,在res中就会多出一个属性res.body
  • extended: false:表示使用系统模块querystring来处理传入的参数,也是官方推荐的
  • extended: true:表示使用第三方模块qs来处理传入的参数.
2) post接口-json格式的参数

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

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

postman操作
在这里插入图片描述

后端

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

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

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

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

enctype="multipart/form-data"

对应postman的操作如下:

步骤

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来获取其它参数

五.理解接口传参

1.请求报文

我们一般使用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来决定。
    在这里插入图片描述

2.传参途径

  • 方法一:请求行。常见方式如下:
    • 使用ajax技术,通过get方式传参。
    • 在浏览器地址栏中输入接口地址并补充上查询字符串
  • 方法二:请求体
    • ajax中的post, put, delete可以从请求体中进行传参。

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

3.后端处理

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

名字: /api

参数:name: 用户名,pwd:密码,avatar头像文件。

格式:formdata.

方式:post
名字: /api2

参数:name: 用户名,pwd:密码

格式:application/x-www-form-encoded (普通键值对)

方式:post
名字: /api3

参数:name: 用户名,pwd:密码

格式:application/json

方式:post

总结

传参方式前端 content-type后端框架express
请求行get方式req.query
请求体application/x-www-form-urlencodeapp.use(express.urlencoded()); req.body
请求体application/jsonapp.use(express.json());
请求体multipart/form-data1. 引入包 const multer = require(‘multer’); 2. 配置app.post(’/apiname’, upload.single(), req.body)

六.接口传参-整体示例

目录结构

-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>

后端

// 实现get接口

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)
})

// 用来JSON格式的数据
// 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端口启动了'); 
})
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值