赞
踩
Node.js其本质和浏览器一样是一个JavaScript运行环境。浏览器的运行环境为V8引擎+浏览器内置API(BOM、DOM、Canvas);而node.js的运行环境是V8引擎+node提供的API(fs、path、http)。它使JavaScript可以编写后端。
它提供一系列的方法和属性,用来满足用户对文件的操作需求
使用语法:
加载 fs 模块,得到 fs 对象
const fs = require('fs')
fs.writeFile('文件路径', '写入内容', err => {
// 写入后的回调函数
})
fs.readFile('文件路径', (err, data) => {
// 读取后的回调函数
// data 是文件内容的 Buffer 数据流
})
/** * 目标:使用 fs 模块,读写文件内容 * 语法: * 1. 引入 fs 模块 * 2. 调用 writeFile 写入内容 * 3. 调用 readFile 读取内容 */ // 1.加载fs模块对象 const fs = require('fs') // 2.写入文件内容 fs.writeFile('./test.txt', 'hello,Node.js', (err) => { if(err) console.log(err) else console.log('写入成功') }) // 3.读取文件内容 fs.readFile('./test.txt', (err, data) => { if (err) console.log(err) // data是buffer16进制数据流对象 // toString()转换成字符串 //<Buffer 68 65 6c 6c 6f 2c 4e 6f 64 65 2e 6a 73> else console.log(data.toString()) })
const path = require('path')
const path = require('path')
const fs = require('fs')
// 注意: ../ 会抵消前面的路径
// const pathStr = path.join('/a', '/b/c', '../../', './d', 'e')
// console.log(pathStr) // \a\b\d\e
// fs.readFile(__dirname + '/files/1.txt')
fs.readFile(path.join(__dirname, './files/1.txt'), 'utf8', function(err, dataStr) {
if (err) {
return console.log(err.message)
}
console.log(dataStr)
})
const path = require('path')
// 定义文件的存放路径
const fpath = '/a/b/c/index.html'
// const fullName = path.basename(fpath)
// console.log(fullName)
const nameWithoutExt = path.basename(fpath, '.html')
console.log(nameWithoutExt) //输出index
const path = require('path')
// 这是文件的存放路径
const fpath = '/a/b/c/index.html'
const fext = path.extname(fpath)
console.log(fext)//输出.html
是用来创建 web 服务器的模块,通过 http模块提供的http.createServer() 方法,就能方便的把一台普通的电脑,变成一台Web服务器,从而提供资源服务
// 1. 导入 http 模块
const http = require('http')
// 2. 创建 web 服务器实例
const server = http.createServer()
// 3. 为服务器实例绑定 request 事件,监听客户端的请求
server.on('request', function (req, res) {
console.log('Someone visit our web server.')
})
// 4. 启动服务器
server.listen(8080, function () {
console.log('server running at http://127.0.0.1:8080')
})
const http = require('http') const server = http.createServer() // req 是请求对象,包含了与客户端相关的数据和属性 server.on('request', (req, res) => { // req.url 是客户端请求的 URL 地址 const url = req.url // req.method 是客户端请求的 method 类型 const method = req.method const str = `Your request url is ${url}, and request method is ${method}` console.log(str) // 调用 res.end() 方法,向客户端响应一些内容 res.end(str) }) server.listen(80, () => { console.log('server running at http://127.0.0.1') })
Node.js中每一个文件都是一个独立的模块,项目由多个模块组成
由于各个模块的属性和函数是私有的,如果对外使用,则需要标准语法导入、导出,即 CommonJS 标准
module.exports = {
对外属性名: 模块内私有变量
}
const 变量名 = require('模块名或路径')
// Node.js 环境内置模块直接写模块名(例如:fs,path,http)
// 自定义模块:写模块文件路径(例如:./utils.js)
代码实现:
导出
/**
* 目标:基于 CommonJS 标准语法,封装属性和方法并导出
*/
const baseURL = 'http://hmajax.itheima.net'
const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
// 导出
module.exports = {
url: baseURL,
arraySum: getArraySum
}
/**
* 目标:基于 CommonJS 标准语法,导入工具属性和方法使用
*/
// 导入
const obj = require('./utils.js')
console.log(obj)
const result = obj.arraySum([5, 1, 2, 3])
console.log(result)
CommonJS 规范为 Node.js 环境中默认的,后来官方推出 ECMAScript 标准语法
注意:Node.js 默认只支持 CommonJS 标准语法,如果想要在当前项目环境下使用 ECMAScript 标准语法,请新建 package.json 文件设置 type: ‘module’ 来进行设置
{ “type”: "module" }
export default {
对外属性名: 模块内私有变量
}
import 变量名 from '模块名或路径'
语法实现:
导出:
/**
* 目标:基于 ECMAScript 标准语法,封装属性和方法并"默认"导出
*/
const baseURL = 'http://hmajax.itheima.net'
const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
// 默认导出
export default {
url: baseURL,
arraySum: getArraySum
}
/**
* 目标:基于 ECMAScript 标准语法,"默认"导入,工具属性和方法使用
*/
// 默认导入
import obj from './utils.js'
console.log(obj)
const result = obj.arraySum([10, 20, 30])
console.log(result)
export 修饰定义语句
import { 同名变量 } from '模块名或路径'
语法实现:
utils.js 导出
/**
* 目标:基于 ECMAScript 标准语法,封装属性和方法并"命名"导出
*/
export const baseURL = 'http://hmajax.itheima.net'
export const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
/**
* 目标:基于 ECMAScript 标准语法,"命名"导入,工具属性和方法使用
*/
// 命名导入
import {baseURL, getArraySum} from './utils.js'
console.log(obj)
console.log(baseURL)
console.log(getArraySum)
const result = getArraySum([10, 21, 33])
console.log(result)
将模块,代码,其他资料整合成一个文件夹,这个文件夹就叫包
包分类:
项目包:主要用于编写项目和业务逻辑
软件包:封装工具和方法进行使用
/**
* 目标:使用 npm 下载 dayjs 软件包来格式化日期时间
* 1. (可选)初始化项目清单文件,命令:npm init -y
* 2. 下载软件包到当前项目,命令:npm i 软件包名称
* 3. 使用软件包
*/
// 3. 使用软件包
const dayjs = require('dayjs')
const nowDateStr = dayjs().format('YYYY-MM-DD')
console.log(nowDateStr)
1.安装:
npm i express@4.17.1
2.创建基本的Web 服务器
3…监听 GET 、POST请求
4.把内容响应给客户端 res.send()
5.获取URL 中携带的查询参数:通过 req.query 对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数
6.获取URL 中的动态参数:通过 req.params 对象,可以访问到URL中,通过:匹配到的动态参数
// 1. 导入 express const express = require('express') // 2. 创建 web 服务器 const app = express() // 4. 监听客户端的 GET 和 POST 请求,并向客户端响应具体的内容 app.get('/user', (req, res) => { // 调用 express 提供的 res.send() 方法,向客户端响应一个 JSON 对象 res.send({ name: 'zs', age: 20, gender: '男' }) }) app.post('/user', (req, res) => { // 调用 express 提供的 res.send() 方法,向客户端响应一个 文本字符串 res.send('请求成功') }) app.get('/', (req, res) => { // 通过 req.query 可以获取到客户端发送过来的 查询参数 // 注意:默认情况下,req.query 是一个空对象 console.log(req.query) res.send(req.query) }) // 注意:这里的 :id 是一个动态的参数 app.get('/user/:ids/:username', (req, res) => { // req.params 是动态匹配到的 URL 参数,默认也是一个空对象 console.log(req.params) res.send(req.params) }) // 3. 启动 web 服务器 app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
1.路由匹配过程:
用法:
1)创建路由模块对应的 .js文件
2)调用 express.Router()函数创建路由对象
3)向路由对象上挂载具体的路由
4)使用 module.exports 向外共享路由对象
var express = require('express') //1.导入express
var router = express.Router() //2.创建路由对象
router.get('/user/list', function (req,res) { //3.挂载获取用户列表的路由
res.send('Get user list')
})
router.post('/user/add', function (req,res) { //4.挂载添加用户的路由
res.send('Add new user')
})
moudle.export = router //5.向外导出路由对象
5)使用app.use()函数注册路由模块
//1.导入路由模块
const userRouter = require('./router/user.js')
//2.使用app.use()注册路由模块,并添加统一的访问前缀 /api
app.use('/api',userRouter)
//包含 req, res, next 三个参数,next() 参数把流转关系交给下一个中间件或路由
const mw = function(req, res, next){
next()
}
const express = require('express') const app = express() // // 定义一个最简单的中间件函数 // const mw = function (req, res, next) { // console.log('这是最简单的中间件函数') // // 把流转关系,转交给下一个中间件或路由 // next() // } // // 将 mw 注册为全局生效的中间件 // app.use(mw) // 这是定义全局中间件的简化形式 app.use((req, res, next) => { console.log('这是最简单的中间件函数') next() }) app.get('/', (req, res) => { console.log('调用了 / 这个路由') res.send('Home page.') }) app.get('/user', (req, res) => { console.log('调用了 /user 这个路由') res.send('User page.') }) app.listen(80, () => { console.log('http://127.0.0.1') })
// 导入 express const express = require('express') // 创建服务器实例 const app = express() // 配置解析表单数据的中间件 app.use(express.urlencoded({ extended: false })) // 必须在配置 cors 中间件之前,配置 JSONP 的接口 app.get('/api/jsonp', (req, res) => { // TODO: 定义 JSONP 接口具体的实现过程 // 1. 得到函数的名称 const funcName = req.query.callback // 2. 定义要发送到客户端的数据对象 const data = { name: 'zs', age: 22 } // 3. 拼接出一个函数的调用 const scriptStr = `${funcName}(${JSON.stringify(data)})` // 4. 把拼接的字符串,响应给客户端 res.send(scriptStr) }) // 一定要在路由之前,配置 cors 这个中间件,从而解决接口跨域的问题 const cors = require('cors') app.use(cors()) // 导入路由模块 const router = require('./16.apiRouter') // 把路由模块,注册到 app 上 app.use('/api', router) // 启动服务器 app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
1.连接数据库
2.了解主界面组成部分
3.创建数据库
4.创建数据表
5.向表中写入数据
//获取数据表
select * from users
//从user表中获取username和password的内容
select username, password from user
把 users表中id为7的用户密码,更新为888888
从 users表中,删除id 为4的用户,示例如下
//1.查询status为1的所有用户
SELECT * FROM use WHERE status=1
//2.查询id大于4的所有用户
OM use WHERE status>4
1.安装 mysql 模块
npm i mysql
2.配置mysql
const mysql = require('mysql')
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'test',
})
3.检测是否能正常工作
db.query('select 1', (err, results) => {
if (err) return console.log(err.message)
console.log(results)
})
4.使用 mysql 模块操作 MySQL 数据库
// 查询 users 表中所有的数据
/* const sqlStr = 'select * from users'
db.query(sqlStr, (err, results) => {
// 查询数据失败
if (err) return console.log(err.message)
// 查询数据成功
// 注意:如果执行的是 select 查询语句,则执行的结果是数组
console.log(results)
}) */
// 向 users 表中,新增一条数据,其中 username 的值为 Spider-Man,password 的值为 pcc123 /* const user = { username: 'Spider-Man', password: 'pcc123' } // 定义待执行的 SQL 语句 const sqlStr = 'insert into users (username, password) values (?, ?)' // 执行 SQL 语句 db.query(sqlStr, [user.username, user.password], (err, results) => { // 执行 SQL 语句失败了 if (err) return console.log(err.message) // 成功了 // 注意:如果执行的是 insert into 插入语句,则 results 是一个对象 // 可以通过 affectedRows 属性,来判断是否插入数据成功 if (results.affectedRows === 1) { console.log('插入数据成功!') } }) */ ------------------------------------------------------------------ //插入数据便捷方式 /* const user = { username: 'Spider-Man2', password: 'pcc4321' } // 定义待执行的 SQL 语句 const sqlStr = 'insert into users set ?' // 执行 SQL 语句 db.query(sqlStr, user, (err, results) => { if (err) return console.log(err.message) if (results.affectedRows === 1) { console.log('插入数据成功') } }) */
// 演示如何更新用户的信息 /* const user = { id: 6, username: 'aaa', password: '000' } // 定义 SQL 语句 const sqlStr = 'update users set username=?, password=? where id=?' // 执行 SQL 语句 db.query(sqlStr, [user.username, user.password, user.id], (err, results) => { if (err) return console.log(err.message) // 注意:执行了 update 语句之后,执行的结果,也是一个对象,可以通过 affectedRows 判断是否更新成功 if (results.affectedRows === 1) { console.log('更新成功') } }) */ ----------------------------------------------------------------------------- // 演示更新数据的便捷方式 /* const user = { id: 6, username: 'aaaa', password: '0000' } // 定义 SQL 语句 const sqlStr = 'update users set ? where id=?' // 执行 SQL 语句 db.query(sqlStr, [user, user.id], (err, results) => { if (err) return console.log(err.message) if (results.affectedRows === 1) { console.log('更新数据成功') } }) */
const sql = 'delete from users where id=?'
//4代表user.id
//若SQL语句中有多个占位符,则必须使用数组为每个占位符指定具体的值
//若SQL语句中只有一个占位符,则可以省略
db.query(sql, 4, (err, results) => {
if (err) return console.log(err.message)
if (results.affectedRows === 1) console.log('删除数据成功')
})
由于使用 delete 语句会真正删除数据,保险起见,使用标记删除的形式,模拟删除的动作。即在表中设置状态status字段,标记当前的数据是否被删除
const sqlStr = 'update users set status=? where id=?'
db.query(sqlStr, [1, 6], (err, results) => {
if (err) return console.log(err.message)
if (results.affectedRows === 1) {
console.log('标记删除成功')
}
})
目前主流的有两类:基于服务端渲染的传统Web开发模式、基于前后端分离的新型Web开发模式
1)服务端渲染的传统Web开发模式:服务器发送给客户端的 HTML 页面,是在服务器通过字符串的拼接动态生成的→客户端不需要使用 Ajax 额外请求页面的数据
利:前端耗时短;有利于SEO
缺点:占用服务器资源;不利于前后的分离
app.get('/index.html', (req, res) => {
//1.要渲染的数据
const user = { name: 'Bruce', age: 29 }
//2.服务器端通过字符串的拼接,动态生成HTML内容
const html = `<h1>username:${user.name}, age:${user.age}</h1>`
//3.把生成好的页面内容响应给客户端→故客户端拿到的是带有真实数据的HTML页面
res.send(html)
})
2)前后端分离的 Web 开发模式:即后端只负责提供API 接口,前端使用 Ajax 调用接口的开发模式
3)应用场景:
工作原理:
安装express-session中间件
npm install express-session
const session = require('express-session')
app.use(
session({
secret: '做一只猫', // secret 属性的值为任意字符串
resave: false, //固定写法
saveUninitalized: true //固定写法
})
)
app.post('/api/login', (req, res) => {
//判断用户提交的登录信息是否正确
if(req.body.username !== 'admin' || req.body.password !== '000000'){
return res.send({status: 1, msg: '登录失败'})
}
req.session.user = req.body //将用户的信息存储到S
req.session.isLogin = true
res.send({ status: 0, msg: 'login done' })
})
app.get('/api/username', (req, res) => {
//判断用户是否登录
if (!req.session.isLogin) {
return res.send({ status: 1, msg: 'fail' })
}
res.send({ status: 0, msg: 'success', username: req.session.user.username })
})
app.post('/api/logout', (req, res) => {
// 清空当前客户端的session信息
req.session.destroy()
res.send({ status: 0, msg: '退出登录成功' })
})
当前端需要跨域请求后端接口的时候,推荐使用JWT认证机制
工作原理:
JWT组成部分:Header(头部)、Payload(有效荷载)、Signature(签名),三者使用.
分隔
使用方法:把 JWT 放在 HTTP 请求头的 Authorization 字段中
Authorization: Bearer <token>
Express 使用 JWT
1)安装JWT相关的包
ljsonwebtoken 用于生成 JWT 字符串
express-jwt用于将 JWT 字符串解析还原成JSON 对象
//安装多个包中间用空格隔开
npm install jsonwebtoken express-jwt
2)导入 JWT 相关的包:使用 require() 函数,分别导入 JWT相关的两个包
//1.导入用于生成字符串的包
const jwt = require('jsonwebtoken')
//2.导入用于将客户端发送过来的IWT字符串,解析还原称JSON对象的包
const expressJWT = require('express-jwt')
3)定义secret 密钥:
为保证 JWT 字符串安全性,需定义一个用于加密和解密的secret密钥
/ 密钥可以为任意字符串
const secretKey = 'dimple'
4)在登录成功后生成 JWT 字符串
调用 jsonwebtoken 包提供的sign()方法,将用户的信息加密成JWT字符串,响应给客户端
app.post('/api/login', (req, res) => {
//用户登录成功后,生成JWT字符串,通过token属性响应给客户端
res.send({
status: 200,
message: '登录成功',
// 调用jwt.sign() 生成 JWT 字符串,三个参数分别是用户信息对象,加密密钥,配置对象
token: jwt.sign({username: userInfo.username}, secretKey, {expiresIn: '30s'})
})
})
5)将JWT 字符串还原为 JSON 对象
// unless({ path: [/^\/api\//] }) 指定哪些接口无需访问权限
app.use(expressJWT({
secret: secretKey
}).unless({ path: [/^\/api\//] }))
6)使用req.user 获取用户信息
app.get('/admin/getinfo', (req, res) => {
console.log(req.user)
res.send({
status: 200,
message: '获取信息成功',
//data: req.user
//6.0版本后改用req.auth
data: req.auth
})
})
7)捕获解析JWT 失败后产生的错误
app.use((err, req, res, next) => {
//token解析失败导致的错误
if (err.name === 'UnauthorizedError') {
return res.send({ status: 401, message: 'Invalid token' })
}
//其它原因导致的错误
res.send({ status: 500, message: 'Unknown error' })
})
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。