Nodejs学习

本文介绍了Node.js中的核心模块,如Buffer的创建、文件系统(fs)的读写操作、HTTP服务端创建、Express框架的使用以及MongoDB数据库操作。同时,涉及了文件流、MIME类型设置、中间件机制、EJS模板引擎和会话控制等方面,是Node.jsWeb开发的基础知识总结。
摘要由CSDN通过智能技术生成

注意事项:无法使用DOM和BOM的API,可以使用console和定时器,顶级对象为global

1 创建buffer


Buffer.alloc(10)

//不会对旧数据清空,创建速度比buffer快
Buffer.allocUnsafe(10)

2 fs模块

(1)写入文件

const fs = require('fs')

//异步写入
fs.writeFile('./1.txt','', err => {
	if(err){
		console.log('失败')
	} else {
		console.log('成功')	
	}
})

//同步写入
fs.writeFileSync('./1.txt','')

(2)追加写入

fs.appendFile(',/1.txt','')
fs.appendFileSync(',/1.txt','')

(3)流式写入

const ws = fs.createWriteStream('./1.txt')
ws.write('11111')
ws.close()

(4)读取文件

fs.readFile('',(err,data)=>{
	console.log(data)
})

(5)流式读取

const rs = fs.createReadStream()
//每次读取64kb数据
rs.on('data', chunk => {})

//读取结束
rs.on('end', ()=> {})

实现文件复制:

const data = fs.readFileSync('./1.txt')
fs.writeFileSync('./2.txt',data)

//使用流方法占用内存少
const rs = fs.createReadStream('./1.txt')
const ws = fs.createWriteStream('./2.txt')

rs.on('data',chunk => {
	ws.write(chunk)
})


rs.pipe(ws)

(6)文件重命名和移动
本质在更改文件路径

fs.rename('./1.txt','./2.txt',err=>{})
//移动
fs.rename('./1.txt','../data/1.txt',err=>{})

(7)删除文件

fs.unlink('./1.txt',err=>{})

fs.rm('./1.txt',err=>{})

(8)文件夹操作

//创建文件夹
fs.mkdir('./data',err=>{})
//创建子文件夹
fs.mkdir('./data/a',{recursive: true}, err => {})

//读取文件夹
fs.readdir('./data', (err,data)=>{})

//删除文件夹
fs.rmdir('./data',err => {})

//删除子文件夹
fs.rm('/a')
fs.rmdir('/a', { recursive: true }, err=>{})

(9)查看资源状态

fs.stat('./1.txt',(err,status)=> {})

(10)批量重命名

const files = fs.readdirSync()

files.forEach(item=>{
	let data = item.split('-')
	let [ num, name ] = data 
	if(Number(num)<10){
		num = `0${num}`
	}
	let newName = num + '-' + name
	fs.renameSync(`./code/${item}`,`./code/${newName}`)
})

3 path模块

const path = require('path')
//前面是绝对路径,后面是相对路径
path.resolve(_dirname,'index.html')

//解析路径
let str =  'D:\\nodeJS\\index.js'
path.parse(str)

//获取文件名
path.basename(str)

//获取文件夹路径
path.dirname(str)

//获取文件扩展名
path.extname(str)

4 HTTP

(1)请求行:请求方法 URL HTTP协议版本号 GET https://www.baidu.com http1.1

(2)响应行:HTTP协议版本号 响应状态码 响应状态描述http1.1 200 OK

5 创建HTTP服务端

const http = require('http')

const server = http.createServe((request,respond)=>{
	//获取请求方法
	request.method
	//获取请求的URL,只包含url的路径与查询字符串
	request.url

	//获取路径
	let res = url.parse(request.url)
	const pathname = res.pathname
	//查询字符串
	const query = res.query

	//获取http协议的版本号
	request.httpVersion
	//获取http的请求头
	request.headers
	//解决响应体中文乱码
	response.setHeader('content-type','text/html;charset=utf-8')
	//设置响应体
	response.end('hello')
})

server.listen(9000,() => {
	console.log(111)
})

6 设置MIME类型

MIME类型用于表示文档、文字或字节流的性质和格式

通过设置content-type来表明响应体的MIME类型

  • html:text/html
  • css:text/css
  • js:text/javascript
  • png:image/png
  • jpg:image/jpeg
  • gif:image/gif
  • mp4:video/mp4
  • mp3:video/mpeg
  • json:application/json

7 Get和Post请求场景

Get请求情况

  • 直接输入url访问
  • a链接
  • link引入css
  • script引入js
  • video和audio引入多媒体
  • img引入图片

8 express框架

(1)获取路由参数

app.get('/:id.html', (req,res) => {
	//所有路由参数req.params
	req.params.id
})

(2)express响应设置

app.get('', (req, res) => {
	res.status(404)
	res.set()	//设置响应头
	res.send('')	//设置响应体
	res.end()
	//连贯操作
	res.status(404).set('','').send('hello')
	
	//重定向
	res.redirect('')	
	//下载响应
	res.download()
	//响应json
	res.json()
	//响应文件内容
	res.sendFile(__dirname+'./1.html')
})

(3)express中间件

使用函数封装公共操作,简化代码

//记录url和ip地址
const getUrlIp = (req, res, next) => {
	const { url, ip } = req
	fs.appendFileSync(path.resolve(__dirname,'./access.log'),`${url} ${ip}\r\n`)
	next()
}

app.use(getUrlIp)

//静态资源中间件设置
app.use(express.static(__dirname+'/public'))

使用中间件获取请求体数据

const bodyParser = require('body-parser')

//解析json格式的请求体中间件
const jsonParse = bodyParser.json()

//解析queryString格式请求体的中间件
const urlencodedParser =  bodyParser.urlencoded({extended: false})

app.post('/login', urlencodedParser , (req, res) => {
  
  console.log(req.body)
  //获取用户名和密码
  res.send('获取用户的数据')
})

实现防盗链

app.use((req, res, next) => {
	let referer = req.get('referer')
	if(referer){
		let url = new URL(referer)
		let hostname = url.hostname
		if(hostname !== '127.0.0.1'){
			res.status(404).send('not found')
			return
		}	
	}
	next()
})

(4)路由模块化

const router = express.Router()

router.get('/admin',(req,res)=>{})

module.exports = router
const homeRouter =  require('/routes/homeRouter')
app.use(homeRouter)

(5)ejs实现列表渲染

let res = ejs.render(`<ul>
	<% arr.forEach(item => { %>
		<li><%= item %></li>
	<%}) %>
</ul>`,{arr})

(6)ejs实现条件渲染

let res = ejs.render(`
	<% if(isLogin){ %>
	<span>11111</span>
	<% }else{ %>
	<span>222</span>
	<% } %>	
`, {isLogin})

(7)在express中使用ejs

//设置模板引擎
app.set('view engine','ejs')
//设置模板文件存放位置
app.set('views',path.resolve(__dirname,'./views'))
app.get('/home', (req, res) => {
	let title = 'xzh'
	res.render('home', { title })

})

在views文件夹下新建home.ejs文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h2>测试<%= title %></h2>
  
</body>
</html>

(8)设置路由前缀

app.use('/',indexRouter)
app.use('/users',userRouter)

(9)处理文件上传
使用formidable插件

const formidable = require('formidable')

router.post('/upload', (req, res, next) => {
	const form = formidable({
		multiples: true,
		//设置上传文件保存目录
		uploadDir: __dirname + '/../public/images',
		//保存文件后缀
		keepExtensions: true
	})
	form.parse(req, (err, fields, files) => {
		if(err){
			next(err)
			return	
		}	
		let url = '/images/' + files.upload.newFilename
		res.send(url)
	})
})

9 记账本效果实现

(1)使用lowdb保存数据

const low = require('lowdb')

const FileSync = require('lowdb/adapters/FileSync')

//写入的文件名字
const adapter = new FileSync('db,json')

//获取db对象
const db = low(adapter)

//初始化数据
db.defaults({posts:[], user: []}).write()

//写入数据
db.get('posts').push({id: 1}).write()

//获取数据
db.get('posts').value()

//删除数据(返回值为删除的对象)
let res = db.get(posts).remove({id: 1}).write()

//更新数据
db.get('post').find({id: 1}).assign({title: '222'})

(2)新增账单记录

router.post('/account', (req, res, next) => {
	let id = shortid.generate()
	db.get('accounts').push({ id:id, ...req.body }).write()
	res.render('success', { msg: '添加成功', url: '/account' })

})

(3)渲染账单列表

<% accounts.forEach(item => {}) %>
	<div><%= item.title%></div>
	<p class="<%= item.type==='-1'? 'panel-danger': 'panbel-success'%>"></p>
<% }) %>

(4)删除账单数据
根据id删除数据

router.get('/account/:id', (req, res) => {
	let id = req.params.id
	db.get('accounts').remove({id: id}).write()
})

9 Mongodb数据库

  • 显示所有数据库:show dbs
  • 切换数据库:use 数据库名
  • 显示当前所在数据库:db
  • 删除当前数据库:先切换,db.dropDatabase()
  • 创建集合:db.createCollection(‘’)
  • 显示当前数据库所有集合:show collections
  • 删除某个集合:db.集合名.drop()
  • 重命名集合:db.集合名.renameCollection(‘’)
  • 插入文档:db.集合名.insert(‘’)
  • 查询文档:db.集合名.find(查询条件)
  • 更新文档:db.集合名.update(查询条件,新的文档),默认覆盖全部数据,如果想只修改某条数据,如下:db.集合名.update({name: ‘xzh’},$set:{age: 19})
  • 删除文档:db.集合名.remove(查询条件)

10 mongoose

用于操作mongodb数据库
(1)连接数据库

const mongoose = require('mongoose')

mongoose.connect('mongodb://127.0.0.1:27017/user')
mongoose.connection.on('open', () => {
	console.log('success')
})

mongoose.connection.on('error', () => {
	console.log('failed')
})

setTimeout(() => {
	mongoose.disconnect()
}, 2000)

(2)插入文档

mongoose.connection.once('open', () => {
	//创建文档的结构对象属性及属性类型
	let bookSchema = new mongoose.Schema({
		name: String,
		age: Number 	
	})
	//创建模型对象(创建集合名称,结构对象)
	let bookModel = mongoose.model('books', bookSchema)
	//新增
	BookModel.create({
		name: 'xzh'
		age: 18	
	}, (err, data) => {
		//data为插入成功的文档对象
	})
	//删除一条数据
	BookModel.deleteOne({_id:''}, (err, data)=>{})
	//批量删除
	BookModel.deleteMany({isLogin: false }, ()=>{})
	//更新单条数据
	BookModel.updateOne({name: 'xzh'}, {price: 9.9},()=>{})
	//批量更新
	BookModel.updateMany({isLogin: false}, {price: 9.9},()=>{})
	//读取数据
	BookModel.findOne({ name: 'xzh'}, () => {})
	//根据id获取数据
	BookModel.findById(,()=>{})
	//批量获取
	BookModel.find()
})

(3)条件语句

  • >:$gt
  • <:$lt
  • >=:$gte
  • <=:$lte
  • !==:$ne
//寻找小于20
bookModel.find({ price: $lt:20})
  • or:bookModel.find({ $or:[{name:'xzh'},{name: 'zz'} ] })

  • and:bookModel.find({ $and:[{name:'xzh'},{name: 'zz'} ] })

    (4)字段筛选

  • 0:不需要的值

  • 1:需要的值

model.find().select({_id:0}).exec((err,data) => {})

(5)数据排序

  • 1:升序
  • -1:降序
model.find().sort({hot: 1}).exec(()=>{})

(6)数据截取

  • skip:跳过,例如跳过1-3,取排序4-6的数据
  • limit:限制,取出数据的长度
model.find().skip(10).limit(10).exec(()=>{})

(7)代码模块化

module.exports = {
	DBHOST: '127.0.0.1',
	DBPORT: 27017,
	DBNAME: 'user'
}
const { DBHOST, DBPORT, DBNAME } = require('./config')

module.exports = function (success, error) {
	const mongoose = require('mongoose')
	mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`)
	mongoose.connection.once('open', ()=>{
		success()	
	})
	mongoose.connection.on('error', () => {
		error()	
	})
}
const mongoose = require('mongoose')

let bookSchema = new mongoose.Schema({
	name: String,
	age: Number
})

let bookModel = mogoose.model('books',bookSchema)

module.exports = bookModel

const db = require('./db')
const bookModel = require('./bookmodel')

db(()=>{
	bookModel.create({
		name: 'xzh'
		age: 18	
	}, (err, data) => {
		//data为插入成功的文档对象
	})
},()=>{
})

注意:使用model.create没有回调函数,可以使用.then(res=>{})

11 json-server

以JSON文件所在文件夹为工作目录执行命令

json-server --watch db.json

通过http请求对数据库数据进行交互

res.json({
	code: '',
	msg: '',
	data: data,
})

12 会话控制

http是无状态的,它无法区别多次请求是否来自于同一客户端,所以使用会话控制来解决这个问题

(1)express中设置cookie

//设置name为xzh有效期1分钟
res.cookie('name','xzh',{ maxAge: 60*1000})

(2)express中删除cookie

res.clearCookie('name')

(3)express中读取cookie

req.cookies

(4)session中间件配置

const session = require('express-session')
const MongoStore = require('connect-mongo')

app.use(session({
	name: 'sid',	//设置cookie的名字
	secret: 'atguigu',	//参与加密的字符串
	saveUninitialized: false, //是否每次请求都设置一个cookie用来存储sessionId
	resave: true, //是否每次请求时重新保存session
	store: MongoStore.create({
		mongoUrl: 'mongodb://127.0.0.1:27017/project'
	}),
	cookie: {
		httpOnly: true, //无法通过js获取cookie
		maxAge: 3600 * 1000	//设置过期事件
	} 
	
}))

(5)express中session的操作

//设置session信息
res.session.username = 'xzh'

//读取session
req.session.username

//销毁session
req.session.destory(()=>{})

13 对api添加token鉴权

使用jsonwebtoken

const jwt = require('jsonwebtoken')
let token = jwt.sign({
	username: result.username
	_id: result,_id`在这里插入代码片`
},'vsxcvbx',{
	expiresIn: 3600 * 1000 * 24 * 7
})

res.json({
	code: '000',
	msg: '',
	data: token
})
	jwt.vertify(token,'vsxcvbx',(err,data)=>{})

14 mysql使用

import mysql from 'mysql'

export const db = mysql.createConnection({
	host: 'localhost',
	user: 'root',
	password: '123',
	database: 'blog'
})
import { db } from '/db.js'
const q = "SELECT * FROM posts"

db.query(q,[], (err, data)=>{})
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值