nodeJs

模块

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);
})
image-20230202172338954
读写-文件流-写 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)]

获取cookiereq.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~~~~~~~~~~~~~~~~');
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值