Express入门笔记

2022-11-15 21:32:53 浏览数 (1)

Node.js简述

Node.js是基于chrome浏览器中的v8引擎而构建的js运行时环境, 并提供了一系列的工具模块和一个包管理工具npm. Node脱离于浏览器运行, 并提供了一系列自带的os相关接口, 从而使其能像传统后端语言一样操作文件、获取os相关信息等.

  • node.js官网
  • node.js中文网
  • npm官网

安装

代码语言:javascript复制
sudo apt-get install nodejs         # 安装nodejs
sudo apt-get install npm            # 安装npm (node package manager)
node -v                             # 查看node版本
npm -v                              # 查看npm版本

npm常用命令

代码语言:javascript复制
npm help                             # 查看帮助
npm 命令 help
npm config list                      # 查看npm配置信息
npm install --global npm             # 升级npm
npm init                             # 初始化项目(生成package.json文件)      
npm install                          # 根据package.json文件下载安装所有node依赖包
npm install 包名                      # 下载安装node包
npm install 包名@x.x.x                # 下载安装指定版本的node包
npm install 包名 --save               # 下载安装node包且保存依赖性到package.json中
npm uninstall 包名                    # 卸载node包, 保留package.json中的依赖性
npm uninstall 包名 --save             # 卸载node包并清除package.json中的依赖性

安装使用cnpm

npm会去国外服务器下载包, 淘宝在国内做了完整的npmjs.org镜像, 可以用cnpm代替npm下载包.

代码语言:javascript复制
# 安装cnpm
sudo npm install --global cnpm

# 之后使用cnpm代替npm进行install
cnpm install 包名

或者仍然使用npm, 但指定使用淘宝的镜像源进行下载

代码语言:javascript复制
# 每次下载都指定--registry参数
npm install 包名 --registry=https://registry.npm.taobao.org

# 或者直接将该选项加入配置文件中
npm config set registry https://registry.npm.taobao.org

模块

Node.js中的模块概念, 类似于python中的模块, 一个js文件即是一个模块.

加载模块

通过require函数加载模块, 加载模块时会去执行模块内的代码. Node.js加载模块跟python一样, 只有第一次加载时会去执行模块内的代码后将其加载到内存中, 随后再去加载仅仅是将在内存中存在的模块增加一次引用而已, 并不会再去执行模块内代码.

代码语言:javascript复制
// 加载自定义模块, 一个js文件就是一个模块, 去掉后缀名即模块名
const myModule = require('./cai.js')      // 加载当前路径下的cai模块
const myModlue  = require('./cai')        // 与上一句等价

// 加载内置模块: 当require参数不含路径时, 表示加载内置模块
const fs = require('fs')          // 加载file system模块
const http = require('http')      // 加载http模块
对外导出变量

Node.js是模块作用域, 各模块之间相互隔离, 如果需要将模块内变量暴露出去, 则需要通过node的内置对象module.exports导出. require函数的返回值即是导入的模块的module.exports对象.

cai.js

代码语言:javascript复制
const add = function(a, b) {
    return a   b
} 

let str = 'hello world'

// 通过exports对象导出add函数和str变量
module.exports.add = add
module.exports.str = str

hello.js

代码语言:javascript复制
// require返回值即是cai.js中的module.exports对象
const cai = require('./cai')
 
// 通过module.exports对象即可访问到cai模块中的add函数和str变量
let res = cai.add(1, 2)
console.log(res)
console.log(cai.str)

注: 为了使用方便, node内置exports = module.exports, 所以也可以使用exports对象暴露, 但如果需要让require函数返回自定义值, 则必须向module.exports赋值而不是exports

Express

express是基于node.js的web框架, 是node.js的一个第三方模块.

  • express官网
  • express中文官网

安装

代码语言:javascript复制
npm install express --save

server demo

express_demo.js

代码语言:javascript复制
const express = require('express')
const path = require('path')
                 
const app = express()
                 
/* 开放静态资源 */                                                                        
// 127.0.0.1/public/xxx
app.use('/public', express.static(path.join(__dirname, './public')))
// 127.0.0.1/xxx
//app.use(express.static(path.join(__dirname, './public')))

/*
 * 响应get请求
 * req: request 请求
 * res: response 响应
 */
app.get('/', (req, res) => {
    // 通过send方法向浏览器返回响应
    res.status(200).send('hello express!')
}) 

/*
 * 响应post请求
 * req: request 请求
 * res: response 响应
 */
app.post('/login', (req, res) => {
    //   通过json方法向浏览器返回Json数据
    res.status(200).json({
        error: 0,
        msg: 'login success',
    })
})
  
/* 运行服务器, 监听80端口 */
app.listen(80, () => {
    console.log('server is running, listening port 80 ...')
})

运行server

代码语言:javascript复制
sudo node express_demo.js

每次修改代码都要重新运行, 解决方法是用nodemon代替node运行js代码

代码语言:javascript复制
# 安装nodemon
sudo npm install --global nodemon
# 运行server
sudo nodemon express_demo.js

模板引擎art-template

art-template语法

安装

代码语言:javascript复制
npm install --save art-template
npm install --save express-art-template

配置使用

代码语言:javascript复制
const express = require('express')

const app = express()

// 只需这一行配置就可使用express-art-template, 第一个参数为模板文件的后缀名
//app.engine('art', require('express-art-template'))
app.engine('html', require('express-art-template'))

// express-art-template默认去当前项目的views目录寻找模板文件
// 如果需要更改该默认路径, 使用下面这一行代码
//app.set('views', path.join(__dirname, './views))

app.get('/', (req, res) => {
    // 调用render方法渲染模板, 并向模板传递模板对象, expres会自动填充模板变量
    res.render('index.html', {
        title: 'index'
    })
})

app.listen(80, () => {
    console.log('server is running, listening port 80 ...')
})

中间件

**中间件(middleware)**是介于请求到响应的整个流程的一道过程, express中使用app.use方法注册中间件, 每个中间件是一个回调函数, 接收三个参数, 依次为request、response、next回调函数(代表下一个中间件). 在中间件中调用next函数则会将request和response传递给下一个中间件.

代码语言:javascript复制
const express = require('express')
        
const app = express()
 
// 通过use方法注册中间件
app.use((req, res, next) => {
    console.log('the first middleware')
    // 调用下一个中间件
    next()
})   
        
app.use((req, res, next) => {
    console.log('the second middleware')
    next()
})   
        
app.get('/', (req, res) => {
    console.log('get /')                                                                
    res.status(200).send('middleware demo')
})   
        
app.listen(80, () => {
      console.log('server is running, listening port 80 ...')
})

运行后, 访问127.0.0.1, 控制台输出以下内容

代码语言:javascript复制
server is running, listening port 80 ...
the first middleware
the second middleware
get /

中间件默认对所有url进行处理, 如果需要对特定的url进行处理, 可以通过req.url参数来判断

代码语言:javascript复制
app.use((req, res, next) => {
    if (req.url === '/') {
            console.log('the first middleware')
            // 调用下一个中间件
            next()
    }
})

除了通过request对象来获取url外, app.use方法允许接收一个url字符串作为第一个参数

代码语言:javascript复制
app.use('/', (req, res, next) => {
    console.log('the first middleware')
    // 调用下一个中间件
    next()
})

获取请求参数

get请求的参数可以通过req.query获取

代码语言:javascript复制
app.get('/login', (req, res) => {
    /* 通过req.query获取get请求时url的参数, 获取的是key-value形式的object */
    console.log(req.query)
    /* res.send方法向浏览器返回响应 */
    res.send('login cuccessful !')
})

post请求, 在express中没有内置获取post请求参数的api, 需要使用第三方模块body-parser作为中间件进行注册.

body-parser文档

安装

代码语言:javascript复制
npm install body-parser --save

配置使用

代码语言:javascript复制
const express = require('express')
// 加载body-parser模块
const bodyParser = require('body-parser')

const app = express()

/* 配置body-parser */
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.post('/login', (req, res) = > {
    /* 通过req.body获取post请求的参数, 获取的是key-value形式的object */
    consloe.log(req.body)
    /* res.send方法向浏览器返回响应 */
    res.send('login cuccessful !')
})

app.listen(80, () => {
    console.log('server is running, listening port 80 ...')
})

路由模块化

可以将路由相关代码从主入口文件中单独抽离出来, 然后在主入口文件中引用.

router.js

代码语言:javascript复制
const express = require('express')

const router = express.Router()

router.get('/', (req, res) => {
   res.render('index.html')
})

router.get('/login', (req, res) => {
   res.render('login.html')
})

// ......

module.exports = router

app.js

代码语言:javascript复制
const express = require('express')
// 加载路由
const router = require('./router.js')

const app = express()  

app.engine('html', require('express-art-template'))

// 使用路由
app.use(router)

app.listen(80, () => {
    console.log('Server is running ...')
})

状态保持

在express中默认不支持CookieSession, 需要通过第三方模块express-session解决.

安装

代码语言:javascript复制
npm instlal cookie-parser --save  
npm install express-session --save
  • cookie-parse文档
  • express-session文档

配置

代码语言:javascript复制
const express = require('express')
const cookieParser = require('cookie-parser');  
const session = require('express-session')

const app = express()

// 配置cookie
app.use(cookieParser())
// 配置session
app.use(session({
  secret: 'keyboard cat', 
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

使用

代码语言:javascript复制
// 设置cookie, maxAge为过期时间, 以ms为单位
res.cookie('username', 'caicai', { maxAge: 7 * 24 * 3600 * 1000, httpOnly: true});

// 获取cookie
res.cookies.username

// 删除cookie
res.clearCookie('username')

// 设置session
req.session.passwd = 'xixixi'
    
// 获取session
req.session.passwd

// 删除session
delete req.session.passwd

本文作者: Ifan Tsai  (菜菜)

本文链接: https://cloud.tencent.com/developer/article/2164596

版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!

0 人点赞