模块
let http = require('http')
var app = http.createServer((req,res) => {
console.log('100')
// 解决乱码问题
res.setHeader("Content-Type","text/html;charset=utf-8")
res.write('8000端口')
res.end()
})
app.listen(8000)
启动第一个node 模块
导入/导出
写法一
导出模块
var a = '哈喽'
function b(...arg){
let add = 0
arg.forEach((val) => {
add += val
})
return add
}
exports.a = a
exports.b = b
导入模块 – require 方式
let {a,b} = require('./01_导出.js')
console.log(a);
console.log(b(1,2,3,4,5));
运行结果
简写
var a = '哈喽'
function b(...arg){
let add = 0
arg.forEach((val) => {
add += val
})
return add
}
exports.str = {a,b}
导入
let {str} = require('./01_导出.js')
console.log(str);
console.log(str.a)
console.log(str.b(1,2,3));
ps exports = module.exports
fs 读/写
读 readFile
const fs = require('fs')
fs.readFile('./02_.text','utf8',(err,data) => {
if(err){
console.log('读取失败:',err);
}
console.log(data);
})
写 writeFile()
fs.writeFile('./02_.text','阿里巴巴',(err)=> {
console.log(err);
})
writeFile 会替换之前text文件的内容,而不是从后面添加
缓存机制
第一次已经加载过了,会放入缓存区,
第二次重复加载时,会直接在缓存区里直接拿,这样 避免重复加载,提高速度
path
console.log(path)
打印结果
<ref *1> {
resolve: [Function: resolve],
normalize: [Function: normalize],
isAbsolute: [Function: isAbsolute],
join: [Function: join],
relative: [Function: relative],
toNamespacedPath: [Function: toNamespacedPath],
dirname: [Function: dirname],
basename: [Function: basename],
extname: [Function: extname],
format: [Function: bound _format],
parse: [Function: parse],
sep: '\\',
delimiter: ';',
win32: [Circular *1],
posix: <ref *2> {
resolve: [Function: resolve],
normalize: [Function: normalize],
isAbsolute: [Function: isAbsolute],
join: [Function: join],
relative: [Function: relative],
toNamespacedPath: [Function: toNamespacedPath],
dirname: [Function: dirname],
basename: [Function: basename],
extname: [Function: extname],
format: [Function: bound _format],
parse: [Function: parse],
sep: '/',
delimiter: ':',
win32: [Circular *1],
posix: [Circular *2],
_makeLong: [Function: toNamespacedPath]
},
_makeLong: [Function: toNamespacedPath]
}
简单使用
const path = require('path')
let a = 'liu'
let p1 = path.join('file','01.js')
console.log(p1);
console.log(__dirname);
console.log(__filename);
const p2 = path.join(__dirname,'03_path.js')
console.log(p2);
打印结果
path.resolve()
将参数转化为绝对路径
1 不带参数
返回该文件所在文件夹的绝对路径
path.resolve() // D:\D\六星教育\node\练习\01
2 携带参数
情况1 返回 ~文件夹的绝对路径 拼接参数
path.resolve('a.js') // D:\D\六星教育\node\练习\01\a.js
a.js 和 ./a.js 是一样的
多个参数,会向后继续拼接
path.resolve('./a.js','./b.js') // D:\D\六星教育\node\练习\01\a.js\b.js
情况2
以 / 开头,会指定到根目录
console.log(path.resolve('/c.js')); // D:\c.js
根目录继续拼接
console.log(path.resolve('/c','m.js')); // D:\c\m.js
最后一个会覆盖前面的
console.log(path.resolve('/c','m.js','/D')); // D:\D
path.parse
解析路径
path.parse('D:/D/六星教育/node/练习/01/03_path.js')
url 模块
let url = require('url')
console.log(url);
打印结果:
{
Url: [Function: Url],
parse: [Function: urlParse],
resolve: [Function: urlResolve],
resolveObject: [Function: urlResolveObject],
format: [Function: urlFormat],
URL: [class URL],
URLSearchParams: [class URLSearchParams],
domainToASCII: [Function: domainToASCII],
domainToUnicode: [Function: domainToUnicode],
pathToFileURL: [Function: pathToFileURL],
fileURLToPath: [Function: fileURLToPath],
urlToHttpOptions: [Function: urlToHttpOptions]
}
URL
类 URL 解析路径
let {URL} = require('url')
const url = new URL('http://127.0.0.1:8000/login?usernName=卡卡西')
console.log(url);
querystring
字符串拼接
let querystring =require('querystring')
console.log(querystring);
{
unescapeBuffer: [Function: unescapeBuffer],
unescape: [Function: qsUnescape],
escape: [Function: qsEscape],
stringify: [Function: stringify],
encode: [Function: stringify],
parse: [Function: parse],
decode: [Function: parse]
}
stringify
用 & 拼接
let str = querystring.stringify({
username:'admin',
password:'123'
})
console.log(str); // username=admin&password=123
例子:拼接 参数
let str = querystring.stringify({
username:'admin',
password:'123'
})
let oldUrl = path.join(__filename,str)
let newUrl = oldUrl.replace(/\\/g,'/')
console.log(newUrl);
fs!!!!!
模块
let fs = require('fs')
console.log(fs)
{
appendFile: [Function: appendFile],
appendFileSync: [Function: appendFileSync],
access: [Function: access],
accessSync: [Function: accessSync],
chown: [Function: chown],
chownSync: [Function: chownSync],
chmod: [Function: chmod],
chmodSync: [Function: chmodSync],
close: [Function: close],
closeSync: [Function: closeSync],
copyFile: [Function: copyFile],
copyFileSync: [Function: copyFileSync],
cp: [Function: cp],
cpSync: [Function: cpSync],
createReadStream: [Function: createReadStream],
createWriteStream: [Function: createWriteStream],
exists: [Function: exists],
existsSync: [Function: existsSync],
fchown: [Function: fchown],
fchownSync: [Function: fchownSync],
fchmod: [Function: fchmod],
fchmodSync: [Function: fchmodSync],
fdatasync: [Function: fdatasync],
fdatasyncSync: [Function: fdatasyncSync],
fstat: [Function: fstat],
fstatSync: [Function: fstatSync],
fsync: [Function: fsync],
fsyncSync: [Function: fsyncSync],
ftruncate: [Function: ftruncate],
ftruncateSync: [Function: ftruncateSync],
futimes: [Function: futimes],
futimesSync: [Function: futimesSync],
lchown: [Function: lchown],
lchownSync: [Function: lchownSync],
lchmod: undefined,
lchmodSync: undefined,
link: [Function: link],
linkSync: [Function: linkSync],
lstat: [Function: lstat],
lstatSync: [Function: lstatSync],
lutimes: [Function: lutimes],
lutimesSync: [Function: lutimesSync],
mkdir: [Function: mkdir],
mkdirSync: [Function: mkdirSync],
mkdtemp: [Function: mkdtemp],
mkdtempSync: [Function: mkdtempSync],
open: [Function: open],
openSync: [Function: openSync],
opendir: [Function: opendir],
opendirSync: [Function: opendirSync],
readdir: [Function: readdir],
readdirSync: [Function: readdirSync],
read: [Function: read],
readSync: [Function: readSync],
readv: [Function: readv],
readvSync: [Function: readvSync],
readFile: [Function: readFile],
readFileSync: [Function: readFileSync],
readlink: [Function: readlink],
readlinkSync: [Function: readlinkSync],
realpath: [Function: realpath] { native: [Function (anonymous)] },
realpathSync: [Function: realpathSync] { native: [Function (anonymous)] },
rename: [Function: rename],
renameSync: [Function: renameSync],
rm: [Function: rm],
rmSync: [Function: rmSync],
rmdir: [Function: rmdir],
rmdirSync: [Function: rmdirSync],
stat: [Function: stat],
statSync: [Function: statSync],
symlink: [Function: symlink],
symlinkSync: [Function: symlinkSync],
truncate: [Function: truncate],
truncateSync: [Function: truncateSync],
unwatchFile: [Function: unwatchFile],
unlink: [Function: unlink],
unlinkSync: [Function: unlinkSync],
utimes: [Function: utimes],
utimesSync: [Function: utimesSync],
watch: [Function: watch],
watchFile: [Function: watchFile],
writeFile: [Function: writeFile],
writeFileSync: [Function: writeFileSync],
write: [Function: write],
writeSync: [Function: writeSync],
writev: [Function: writev],
writevSync: [Function: writevSync],
Dir: [class Dir],
Dirent: [class Dirent],
Stats: [Function: Stats],
ReadStream: [Getter/Setter],
WriteStream: [Getter/Setter],
FileReadStream: [Getter/Setter],
FileWriteStream: [Getter/Setter],
_toUnixTimestamp: [Function: toUnixTimestamp],
F_OK: 0,
R_OK: 4,
W_OK: 2,
X_OK: 1,
constants: [Object: null prototype] {
UV_FS_SYMLINK_DIR: 1,
UV_FS_SYMLINK_JUNCTION: 2,
O_RDONLY: 0,
O_WRONLY: 1,
O_RDWR: 2,
UV_DIRENT_UNKNOWN: 0,
UV_DIRENT_FILE: 1,
UV_DIRENT_DIR: 2,
UV_DIRENT_LINK: 3,
UV_DIRENT_FIFO: 4,
UV_DIRENT_SOCKET: 5,
UV_DIRENT_CHAR: 6,
UV_DIRENT_BLOCK: 7,
S_IFMT: 61440,
S_IFREG: 32768,
S_IFDIR: 16384,
S_IFCHR: 8192,
S_IFLNK: 40960,
O_CREAT: 256,
O_EXCL: 1024,
UV_FS_O_FILEMAP: 536870912,
O_TRUNC: 512,
O_APPEND: 8,
S_IRUSR: 256,
S_IWUSR: 128,
F_OK: 0,
R_OK: 4,
W_OK: 2,
X_OK: 1,
UV_FS_COPYFILE_EXCL: 1,
COPYFILE_EXCL: 1,
UV_FS_COPYFILE_FICLONE: 2,
COPYFILE_FICLONE: 2,
UV_FS_COPYFILE_FICLONE_FORCE: 4,
COPYFILE_FICLONE_FORCE: 4
},
promises: [Getter]
}
stat 判断是文件还是文件夹
判断是问价还是问价夹
let fs = require('fs')
console.log(fs);
fs.stat('./05',(err,stats) => {
if(err){
console.log(err);
return false
}
else if(stats.isFile()){
console.log("文件");
}
else if(stats.isDirectory()){
console.log("文件夹");
}
})
statSync同步的stat
fs.statSync(path),只接收一个path变量
mkdir 新增文件夹
fs.mkdir('css',(err) => {
if(err){
console.log(err);
return false
}
console.log('ok');
})
读写—writeFile 写
向文件中写入内容,但是会覆盖掉文件之前的内容
fs.writeFile('./05_text.txt','共享单车',(err) => {
if(err){
return false
}
console.log('写入成功');
})
读写—readFile 读取文件内容
fs.readFile('./05_text.txt',(err,data) => {
if(err){
return false
}
console.log(data.toString());
})
读写—文件流-读 createReadStream
let fs = require('fs')
var readStream = fs.createReadStream('07_reader.text')
var str = '' // 保存数据
readStream.on('data',(chunk)=>{
str += chunk
})
readStream.on('end',(chunk)=>{
console.log(str);
})
读写-文件流-写 createWriteStream
var writeStream = fs.createWriteStream('07_reader.text')
for(let i =0;i<200;i++){
let data = `今天是第${i}天\n`
writeStream.write(data,'utf-8')
}
writeStream.end() // 标记写入完成
writeStream.on('finish',()=>{ // 写入完成
console.log('finish');
})
writeStream.on('err',()=>{ // 失败
console.log('err');
})
会覆盖之前的内容
读写-拷贝-pipe
// 可读内容
var readStream = fs.createReadStream('07_reader.text')
// 可写内容
var writeStream = fs.createWriteStream('07_kaobei.text')
// pipe
readStream.pipe(writeStream)
console.log('over');
将 07_reader 的内容拷贝到 07_kaobei 中
readdirSync 读取文件夹
读取文件夹的内容:以数组的形式
返回文件夹内的 文件或者文件夹的名称
const backData = fs.readdirSync('./css')
console.log(backData);
writeFileSync
用于将数据同步写入文件。如果该文件已经存在,则替换该文件
三个参数
-
**file:**它是一个字符串,Buffer,URL或文件描述整数,表示必须在其中写入文件的路径。使用文件描述符将使其行为类似于fs.write()方法。
-
**data:**它是将写入文件的字符串,Buffer,TypedArray或DataView。
-
options:
它是一个字符串或对象,可用于指定将影响输出的可选参数。它具有三个可选参数:
- **encoding:**它是一个字符串,它指定文件的编码。默认值为“ utf8”。
- **mode:**它是一个整数,指定文件模式。默认值为0o666。
- **flag:**它是一个字符串,指定在写入文件时使用的标志。默认值为“ w”。
appendFileSync 新增
fs.appendFileSync('./05_text.txt','添加共享单车',(err) => {
if(err){
return false
}
console.log('写入成功');
})
rename 剪切文件
将 05_text.txt 文件 剪切,放入 css 文件夹中,并重写命名为 line.text
fs.rename('./05_text.txt','./css/line.text',(err) => {
if(err){
return false
}
console.log("修改成功");
})
rmdir 删除文件夹
只能删除空文件夹
fs.rmdir('./05',(err)=>{
if(err){
console.log('err');
return false
}
console.log('成功删除');
})
unlink 删除文件
fs.unlink('./01_导出.js',(err)=>{
if(err){
console.log('err');
return false
}
console.log('成功删除');
})
fs 案例-暴力删除文件
案例-爬取 request
爬取某网站的图片路径
let request = require('request')
let fs = require('fs')
// var writeStream = fs.createWriteStream('08.html')
var writeStream = fs.createWriteStream('08_png.text')
request.get({
url:'https://www.bookuu.com/'
},(err,res,body)=>{
if(err){
console.log(err);
return false
}
let reg = /https:\/\/media2\.v\.bookuu\.com\/activity\/\d+\/\d+\/\d+\.(jpg[\d@!a-z]*|png)/g
var image = body.match(reg)
let onlyImage = Array.from(new Set(image))
onlyImage.forEach(item => {
let imgPath = `${item}\n`
writeStream.write(imgPath)
})
})
爬取视频
request('https://vd2.bdstatic.com/mda-kmeikkhd00xbnbte/sc/cae_h264_nowatermark/1608009010/mda-kmeikkhd00xbnbte.mp4?v_from_s=hkapp-haokan-nanjing&auth_key=1675581913-0-0-3ea494e21138dac19d02a717a1cba456&bcevod_channel=searchbox_feed&cd=0&pd=1&pt=3&logid=3313364182&vid=7247227214287269880&abtest=&klogid=3313364182')
.pipe(fs.createWriteStream('./08_medio/medio.mp4'))
爬取小说
cheerio 模块
let request = require('request')
let fs = require('fs')
let cheerio = require('cheerio')
request('https://huayu.zongheng.com/showchapter/1262941.html',(err,res,body)=>{
if(err) return false
let $ = cheerio.load(body,{decodeEntities:false})
$('.col-4 a').each((index,item)=>{
// console.log(index);
// console.log(item);
// console.log(item.attribs.href);
let href = item.attribs.href
content(href,index)
})
})
function content(url,index){
request(url,(err,res,body)=>{
if(err) return false
let $ = cheerio.load(body,{decodeEntities:false})
let text = $('.content').text()
text= text.replace(/。/g,`\n`)
fs.writeFileSync(`08_text/目录${index+1}.text`,text)
})
}
template 模块
下载
npm i art-template --save
let template = require('art-template')
let fs = require('fs')
fs.readFile('09_template.html',(err,data)=>{
// console.log(data.toString());
let temp = template.render(data.toString(),{
name:'物语',
tv:'少年派'
})
console.log(temp);
})
将09_template.html 中 {{name}} {{tv}} 替换为 物语 少年派
express模块
基本使用
let express = require('express')
var app = express()
app.get('/',(req,res)=>{
res.send('ok')
})
app.get('/home/:name',(req,res)=>{
let {name} = req.params
console.log(req.query);
res.send(`${name}课程`)
})
app.listen(8000,()=>{
console.log('8000监听成功');
})
req.params 与 req.query 的区别
req.params 获取的是动态路由的值(如:/后面的web)
req.query 获取的是?后面的参数
开放指定目录资源
中间件 use
let express = require('express')
var app = express()
app.use(express.static('./public')) // 开放public目录
app.use((req,res)=>{
// res.send('404页面')
res.redirect('./html/404.html') // 当跑错误路径的时候,或直接跳转到这个404页面
})
开放了public目录的文件 app.use(express.static('./public'))
路由重定向res.redirect
express-art-template模块
模板字符串模块
使用该模块的前提是已经下载好了 art-template 模块
let express = require('express')
let app = express()
app.engine('html', require('express-art-template'))
app.get('/roles',(req,res)=>{
res.render('./html/roles.html',{
name:'卡卡西'
})
})
app.listen(8001,()=>{
console.log('8001~~~');
})
express-art-template 模块默认会指向views
目录
所有render 里面的内容必须是在views里面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u7t50pir-1684060988848)(./Img/image-20230205210241950.png)]
post请求
//express框架的自带方法获取post参数
app.use(express.urlencoded({ extended: false }))
app.post(‘/post’, (req, res) => {
if (req.body
.name == ‘zx’ && req.body.psw == ‘123456’) {
res.redirect(‘./html/index.html’)
}
})
通过接口传递图片或者文件
const multiparty = require('multiparty')
const fs = require('fs')
module.exports = (req,res) => {
let form_data = new multiparty.Form()
form_data.parse(req)
form_data.on('part',async part => {
console.log(part.filename);
if(part.filename){
let w = fs.createWriteStream('./public/img/' + part.filename)
console.log('w',w);
part.pipe(w)
}
})
}
文件流
文件流类型有(File,Blob,Arraybuffer,base64)/ 文件流(可以直接传图片,文件等内容)
文件流是二进制数据流,当文件以二进制的方式被传递时,需要借助一些对象,模块进行解析
cookie
下载模块 cookie-parser
基本使用
res.cookie
let express = require('express')
let cookieParser = require('cookie-parser')
let app = express()
app.use(cookieParser())
app.get('/set', (req, res) => {
res.cookie('username00','妈呀')
// console.log(res.cookie);
res.send('cookie')
})
app.listen(8000, () => {
console.log('8000~~~over');
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5XfdPmP-1684060988849)(./Img/image-20230206104216500.png)]
获取cookie
req.cookies
mongoDB 数据库
第1步
127.0.0.1:27017
出现一下 说明数据库配置成功
第二步
下载 mongoose
npm i mongoose --save
第三步
基本使用
一 创建表
let mongoose = require('mongoose')
// 链接数据库
mongoose
.connect('mongodb://localhost:27017/bookShop', {
useNewUrlParser: true, //url字符解析
useUnifiedTopology: true //服务器的监视引擎
})
.then(() => {
console.log('链接成功');
})
.catch(() => {
console.log('链接失败');
})
// 指定表规格
const Schema = mongoose.Schema
let bookSchema = new Schema({
bookName: { type: String, require: true },
bookPrice: { type: Number, require: true },
bookDec: { type: String, require: true },
})
// 建表
const BookData = mongoose.model('bookData', bookSchema)
// BookData.create({bookName:'卡卡西',bookPrice:12,bookDec:'汉坎'})
//导出: 多次利用
module.exports = BookData
// exports.default = BookData
二 create 添加数据
这里引入的时候注意 不能使用 { }
let BookData
= require(‘./13.mongo.js’)
BookData.create(bookData) 添加数据
let express = require('express')
let BookData = require('./13.mongo.js')
let app = express()
app.use(express.static('./public/html/'))
app.use(express.urlencoded({extended:true}))
app.post('/login',(req,res)=>{
// console.log(req.body.bookName);
let {bookName,bookPrice,bookDec} = req.body
let bookData = {
bookName:bookName,
bookPrice:bookPrice,
bookDec:bookDec,
}
BookData.create(bookData)
res.send('login')
})
app.listen(8000,()=>{
console.log('8000!!!');
})
三 查询 find()
第一个参数:查询条件
function find(){
var criteria = {'bookName':'彼得潘与辛德瑞拉'}
BookData.find(criteria,(err,data)=>{
if(err) return
console.log(data);
})
}
find()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hOJG7YRt-1684060988850)(./Img/image-20230206152709309.png)]
$gt | 大于 | |
$gte | 大于等于 | |
$lt | 小于 | |
$ne | 小于等于 | |
$nor | 取反 | |
$or | 或 |
查询数据库中,所有价格小于10的数据
var criteria = {bookPrice:{$lt:10}}
BookData.find(criteria,(err,data)=>{
if(err) return
console.log(data);
})
查询数据库中,书名为 彼得潘与辛德瑞拉 或者 为 小蘑菇 的数据
var criteria = {$or:[{'bookName':'彼得潘与辛德瑞拉'},{'bookName':'小蘑菇'}]}
BookData.find(criteria,(err,data)=>{
if(err) return
console.log(data);
})
$exists | 判断属性是否存在 |
var criteria = {bookName:{$exists:true}}
使用 js 方式进行条件删选
var criteria = {$where:"this.bookName === '小蘑菇'"}
使用 正则 进行条件删选
var criteria = {bookName:/小蘑菇/}
Model.find(conditions, [projection], [options], [callback])参数配置
conditions | 查询条件 | |
---|---|---|
callback | 回调函数 参数err data | |
projection | 返回的内容配置 | |
options | 查询配置选项 |
projection
1:存在
0:不存在
{_id:0,bookName:1,bookPrice:1,bookDec:1}, 返回的数据,没有 _id 这种:只能过滤 _id
'bookName bookDec' 需要查询的字段用空格相连 可以只返回 name 和 dec
BookData.find(
criteria,
{_id:0,bookName:1,bookPrice:1,bookDec:1},
// 'bookName bookDec'
(err,data)=>{
if(err){
console.log(err);
return false
}
console.log(data);
})
// options 查询配置选项 常用skip limit sort
// {skip:2} 略过前2条数据
// {limit:5} 最多返回5条属性
// {sort:{age:1}} 按照age项升序排列
options
skip:2 | 过滤查询后的前两条 | |
---|---|---|
limit:4 | 只获取 4 条数据 | |
sort:{bookPrice:-1} | 排序:按照bookPrice来排序 -1从大到小 1从小到大 |
BookData.find(
criteria,
// {_id:0,bookName:1,bookPrice:1,bookDec:1},
'bookName bookPrice',
{ skip:2,limit:4,sort:{bookPrice:-1}},
(err,data)=>{
if(err){
console.log(err);
return false
}
console.log(data);
})
四 更新
注意 update 已经废弃
updateOne
updateMany
var criteria = {'bookName':'彼得潘与辛德瑞拉'}
BookData.updateOne(
criteria,
// { 'bookDec': '安泽逃跑了' },
{$set:{ 'bookDec': '安泽逃跑了' }},
(err, data) => {
if (err) {
console.log(err);
return false
}
console.log(data);
}
)
跟新成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhc9CvFs-1684060988851)(./Img/image-20230207094636644.png)]
通过id跟新整条数据
BookData.findOneAndUpdate(
{'_id':_id},
req.body,
{new:true},
(err,data)=>{
console.log(data);
}
)
}
4.2 查询/更新嵌套数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r4QIWiNL-1684060988851)(./Img/image-20230320164701582.png)]
Customer.findOneAndUpdate(
// 做两次查询,第一次查询用户id,第二次查询用户购物车中的书籍id
{
'customerToken': customerToken,
customerCart: { $elemMatch: { bookID: bookID } }
},
{ $set: { 'customerCart.$.bookNumber': bookNumber } },
(err, data) => {
if (err) {
console.log(err);
return
}
console.log(data);
if (data) {
console.log('触发', data);
res.send({ code: 0, message: '修改成功' })
}
})
五 删除
六 验证规则
- required: true 必传字段
- minlength: 2 字符串最小长度
- maxlength 10 字符串最大长度
- min: 10 数值最小值
- max: 100 数值最大值
- enum: [‘html’,‘css’,‘javascript’] 枚举,列出当前可以拥有的字段
- trim: true 去除字符前后两边的空格
- validate: 自定义验证器
- default: 默认值
validata
密码长度 5-10 至少包含字母,下划线,数字 中的两个
/^
\w{5,10}$
/.test(value) 要添加开始和结束符号
pwd:{
type:String,
require:true,
// 密码长度 5-10 包含字母,下划线,数字三个中的至少两个
validate:(value)=>{
if(/a-zA-z/.test() + /_/.test(value) + /\d/.test(value)){
return /^\w{5,10}$/.test(value)
}else{
return false
}
}
}
七 中间件
pre
post
pre 在调用 find方法前执行
post 在调用post 方法后执行(data为find返回的数据),会在find方法回调函数前执行
bookSchema.pre('find',(next)=>{
console.log('pre');
next()
})
bookSchema.post('find',(data)=>{
console.log(data);
console.log('post');
})
koa框架
下载 koa
koa-router
koa-router 路由
简单使用
let koa = require('koa')
let Router = require('koa-router')
const app = new koa()
const router = Router() //实例化路由
app.use(router.routes()) // 启动路由
router.get('/',async ctx => {
ctx.body='koa框架!!'
})
app.listen(8000,()=>{
console.log('8000~~~~~~~~~~~~~~~~');
})
ctx 包含 req 和res
参数
http://127.0.0.1:8000/login?username=‘卡卡西’
router.get('/login',async ctx => {
console.log('1',ctx.query);
console.log('2',ctx.request.query);
console.log('3',ctx.querystring);
console.log('4',ctx.url)
ctx.body='koa框架!!'
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TpyWFecJ-1684060988852)(./Img/image-20230207130242928.png)]
静态资源处理
下载 koa-static
let serve = require('')
app.use(serve(__dirname + '/public/html/'))
开放了 public 下的 html 文件夹
POST 请求
const bodyParser = require('koa-bodyparser')
//在启动路由之前配置bodyParser插件
app.use(bodyParser())
ctx.request.body
获取参数
let koa = require('koa')
let Router = require('koa-router')
let serve = require('koa-static')
const bodyParser = require('koa-bodyparser')
const app = new koa()
//在启动路由之前配置bodyParser插件
app.use(bodyParser())
const router = Router()
app.use(router.routes())
app.use(serve(__dirname + '/public/html/'))
router.get('/login',async ctx => {
ctx.redirect('login.html')
})
router.post('/login',async ctx=>{
let {bookName,bookPrice,bookDec} = ctx.request.body
console.log(bookName);
console.log(bookPrice);
console.log(bookDec);
})
app.listen(8000,()=>{
console.log('8000~~~~~~~~~~~~~~~~');
})
oa框架!!’
})
app.listen(8000,()=>{
console.log(‘8000~~~~~~~~~~~~~~~~’);
})
ctx 包含 `req 和res` 参数
**http://127.0.0.1:8000/login?username='卡卡西'**
```javascript
router.get('/login',async ctx => {
console.log('1',ctx.query);
console.log('2',ctx.request.query);
console.log('3',ctx.querystring);
console.log('4',ctx.url)
ctx.body='koa框架!!'
})
[外链图片转存中…(img-TpyWFecJ-1684060988852)]
静态资源处理
下载 koa-static
let serve = require('')
app.use(serve(__dirname + '/public/html/'))
开放了 public 下的 html 文件夹
POST 请求
const bodyParser = require('koa-bodyparser')
//在启动路由之前配置bodyParser插件
app.use(bodyParser())
ctx.request.body
获取参数
let koa = require('koa')
let Router = require('koa-router')
let serve = require('koa-static')
const bodyParser = require('koa-bodyparser')
const app = new koa()
//在启动路由之前配置bodyParser插件
app.use(bodyParser())
const router = Router()
app.use(router.routes())
app.use(serve(__dirname + '/public/html/'))
router.get('/login',async ctx => {
ctx.redirect('login.html')
})
router.post('/login',async ctx=>{
let {bookName,bookPrice,bookDec} = ctx.request.body
console.log(bookName);
console.log(bookPrice);
console.log(bookDec);
})
app.listen(8000,()=>{
console.log('8000~~~~~~~~~~~~~~~~');
})