nodejs

一、cmd终端常用命令

1、dir          显示目录里面的所有文件(包括文件夹和文件)

2、cd..         回到上一级目录

3、cd\          回到根目录

4、cd 路径      跳转到指定的目录(路径可以是绝对路径,也可以是相对路径)

相对路径是相当于当前路径的路径;绝对路径是相对于当前盘符根路径的路径。

5、盘符名称:    切换盘符(比如:d:,回车后就会切换到d盘)

6、cls          清屏(清空屏幕)

7、md 目录名称  创建目录

8、rd 目录名称  删除空目录

9、del 文件名   删除指定的文件

10、del 目录名  删除目录里面的全部文件

11、copy 命令用于复制文件

12、move 命令用于移动文件


打开当前目录里面的文件或程序:文件名.扩展名 回车

我们在cmd窗口中,输入文件名.扩展名 回车,首先它会在当前目录中找该文件是否存在,存在则打开该文件。如果当前目录中没有这个文件,就会到系统变量的path中,遍历所有的路径,找这个文件是否存在,存在则打开文件;如果还是没有,则报错。

二、模块

js程序不能直接运行,必须要在浏览器中运行;在网页中引入js程序时,一定要注意引入的顺序,因为前后js可能是有关系的。综上,引入nodejs解决问题。

在nodejs环境中,每一个独立的js文件,就是一个独立模块。

每个独立的模块是一个私有的作用域,每一个独立模块其实就是独立方法。这个方法,提供了5个参数:exports, require, module, __filename, __dirname。

1、exports对象

nodejs中,导出当前模块的成员,可以用exports,也可以用module.exports。其实exports对象,指向了module.exports对象,最终导出的是module.exports对象。

通常情况下exports

(1)使用exports对象导出

exports导出成员时,不能重新给exports赋值一个新对象,只能一个一个导出。

let money = 10000

let city = '南京'

exports.money = money

exports.city = city

注意:不能采用下面的方式导出成员

 exports = {

    money:money,

    city:city

}

(2)使用module.exports

module.exports导出成员时,既可以一个一个导出,也可以通过赋值一个对象的方式导出。

module.exports.fun1 = fun1

module.exports = {

    money:money,

    city:city,

    fun1:fun1

}

2、require方法

用于导入其他模块里面的成员。

在nodejs中,通过require方法,导入其他模块。一般情况下,我们会通过解构赋值的方式,直接从导入的对象中获取需要的成员。

let {money,city,fun1} = require('./index03.js')

3、module对象

是当前模块本身,它里面的exports对象属性,也是用于导出当前模块里面的成员。

4、__filename变量

返回当前模块文件的绝对路径。

console.log(__filename);// E:\kw\kwstudy\nodeJS\L01\index03.js

5、__dirname变量

返回当前模块文件所在目录的绝对路径。

console.log(__dirname);// E:\kw\kwstudy\nodeJS\L01

三、通过require导入模块

1、require()

require方法,用于导入模块,方法的参数是:模块的标识。

导入模块时,模块标识如果没有文件的后缀名,

(1)首先判断该模块是不是系统模块

(2)如果不是系统模块,再判断是不是第三方模块

(3)如果导入的是自定义包里面的模块,可以省略包里面的具体的文件

// 表示导入自定义math包里的模块,默认是math包里的index.js文件

let math = require('./math')  

2、系统模块

通过系统模块的名称导入。

let path = require('path')

3、第三方模块

通过模块的名称导入(这个名称是package.json文件中name属性对应的名称)。

let math = require('math')

4、自定义模块

通过模块的路径导入,路径可以是相对路径,也可以是绝对路径。

四、global

在node环境中,没有window对象。有一个全局对象global,类似于浏览器环境中的window对象。

五、npm

(1)下载包

备注:install的简写是i,--save的简写是-S,--save-dev的简写是-D,--global的简写-g。

npm install 包名               下载包 (默认会将下载的包添加到生产环境依赖,生产环境依赖的包参与本项目的打包)

npm install 包名 --save        (--save表示下载包,并添加到生产环境依赖)

npm install 包名 --save-dev    (--save-dev表示下载包,并添加到开发环境依赖,只是开发时依赖该包,不参与本项目的打包)

npm install 包名 --global      安装全局插件

使用npm下载第三方包后,会在项目根路径中添加一个package-lock.json文件。该文件是可以删除的,它的作用是记录第三方包的完整信息,方便下次下载包时快速定位该包的信息,省去了查找包的时间。

(2)升级包

npm update 包名                对指定包进行升级

npm update                     升级所有包

[if !supportLists](1)[endif]删除包

备注:remove的简写是r

npm remove 包名                移除包

npm uninstall 包名             卸载包(功能等同于移除包)

(4)下载所有依赖包

npm install/i         根据package.json文件中的依赖关系,下载当前项目所依赖的包

3、npm镜像地址

(1)查看npm镜像地址

npm config get registry

(2)修改npm镜像地址

① npm config edit 打开npm的配置文件,然后修改

registry=http://registry.npm.taobao.org/

② npm config set registry http://registry.npm.taobao.org

(3)还原npm原来的镜像地址

npm config set registry https://registry.npmjs.org/

4、安装cnpm中国npm镜像客户端

npm install cnpm -g    全局安装cnpm

cnpm的所有命令跟npm一样。(唯一的区别是:cnpm install 包名,不会将下载的包默认添加到生产环境依赖。必须要加上--save。)

5、安装nodemon工具

nodemon是一种工具,可以自动监测文件的变化,当有变化时重新启动服务。(需要使用nodemon时,先关闭自动保存)

npm i nodemon -g      全局安装nodemon

nodemon ./index.js运行index.js文件

六、yarn

1、安装yarn包管理工具

npm install yarn -g

2、yarn镜像地址

(1)查看yarn镜像地址

yarn config get registry

(2)修改yarn镜像地址

yarn config set registry http://registry.npm.taobao.org/

(3)还原yarn原理的镜像地址

yarn config set registry http://registry.npmjs.org/

3、yarn的常用命令

(1)下载所有依赖包

yarn install === npm install                注意:npm中install,可以简写成i,yarn中不可以;但是yarn可以省略install。

(2)下载包

yarn add 包名 === npm install 包名 --save    注意:--save可以省略,因为默认就是添加到生产依赖。

yarn add 包名 --dev === npm install 包名 --save-dev

yarn global add 包名 === npm install 包名 --global    注意:npm中--global可以简写成-g。

(3)删除包

yarn remove 包名 === npm remove 包名         注意:npm中remove,可以简写为r,yarn中不可以。

(4)升级包

yarn upgrade 包名 === npm update 包名

yarn upgrade === npm update

七、系统模块path

1、定义

系统模块path,用于操作路径相关。

let path = require('path')

2、join() 路径拼接

path.join('路径','路径',...)   该方法会根据当前nodejs所在的系统环境,返回正确格式的拼接路径。

不同的操作系统,路径的拼接符是不一样的。windows系统中,路径的拼接符是 / 或 \ ;linux系统中,路径的拼接符是 / ;我们用nodeJS开发的程序,将来部署到什么操作系统的服务器上是不确定的。所以,使用join()方法,返回拼接路径。

console.log(path.join('a','b','c','d'))//  a\b\c\d

3、resolve()

带参数,path.resolve(相对路径)方法,返回一个相对路径的绝对路径。

console.log(path.resolve('./file/a.txt')) //  E:\kw\kwstudy\nodeJS\1028\file\a.txt

不带参数,path.resolve()方法,返回当前模块所在目录的绝对路径。

console.log(path.resolve());// E:\kw\kwstudy\nodeJS\1028

全局变量__dirname,也是返回当前模块所在目录的绝对路径

console.log(__dirname);// E:\kw\kwstudy\nodeJS\1028

4、返回指定包(math)的绝对路径

// E:\kw\kwstudy\nodeJS\1028\math

console.log(path.join(path.resolve(),'math'));

七、系统模块path

1、定义

系统模块path,用于操作路径相关。

let path = require('path')

2、join() 路径拼接

path.join('路径','路径',...)   该方法会根据当前nodejs所在的系统环境,返回正确格式的拼接路径。

不同的操作系统,路径的拼接符是不一样的。windows系统中,路径的拼接符是 / 或 \ ;linux系统中,路径的拼接符是 / ;我们用nodeJS开发的程序,将来部署到什么操作系统的服务器上是不确定的。所以,使用join()方法,返回拼接路径。

console.log(path.join('a','b','c','d'))//  a\b\c\d

3、resolve()

带参数,path.resolve(相对路径)方法,返回一个相对路径的绝对路径。

console.log(path.resolve('./file/a.txt')) //  E:\kw\kwstudy\nodeJS\1028\file\a.txt

不带参数,path.resolve()方法,返回当前模块所在目录的绝对路径。

console.log(path.resolve());// E:\kw\kwstudy\nodeJS\1028

全局变量__dirname,也是返回当前模块所在目录的绝对路径

console.log(__dirname);// E:\kw\kwstudy\nodeJS\1028

4、返回指定包(math)的绝对路径

// E:\kw\kwstudy\nodeJS\1028\math

console.log(path.join(path.resolve(),'math'));

八、系统模块fs

1、定义

系统模块fs,用于操作文件相关。

let fs = require('fs')

2、同步方式方式读取文件

同步方式读取文件,指的是文件的读取过程必须是一个一个读取。假如,后面还要读取其他文件,必须要等到前面的文件读取完成了,再读取下一个文件。

(1)读取文件 openSync/readSync/closeSync

① 打开文件,通过openSync方法打开文件,返回值是文件标识(文件标识是一个数字)

let fd = fs.openSync('./file/a.txt','r')

② 读取文件中的内容,通过readSync方法读取文件。

参数1:文件标识

参数2:buffer容器

创建一个buffer容器,用于接收读取到的数据,其实就是开辟一段内存空间(单位是字节)。注意:一个汉字占用三个字节空间。

let buf = Buffer.alloc(30)// 创建30字节的buffer容器

fs.readSync(fd,buf)// 用buf接收fd文件数据

③ 文件读取结束后,需要关闭文件。

fs.closeSync(fd)// 关闭fd文件

[if !supportLists](2)[endif]一般方式读取文件readFileSync()

fs.readFileSync(文件路径)

let buf = fs.readFileSync('./file/a.txt')

console.log('同步:'+buf.toString());

[if !supportLists]1、[endif]同步写入文件

同步方式写入文件的缺陷:如果要写入多个文件,只能一个一个写。

(1)写入一个文件 openSync/writeSync/closeSync

① 打开文件,通过openSync方法打开文件,返回值是文件标识(文件标识是一个数字)

参数1:文件路径,

参数2:打开文件的方式:r是读,w是写,a是追加。

let fd = fs.openSync('./file/b.txt','a')

② 向文件中写入内容(如果需要写入中文,加一个'utf-8';内容是纯英文可以省略)

fs.writeSync(fd,'HelloWorld你好','utf-8')

fs.writeSync(fd,'HelloWorld')

③ 文件写入后,需要关闭文件

fs.closeSync(fd)

(2)一般方式写入文件 writeFileSync()

writeFileSync()方法内部已经完成了文件的打开、读取、关闭操作。

try{

    fs.writeFileSync('./file/a.txt','HelloWorld',{flag:'a'})// 追加参数a要写在对象中

    console.log('同步:写入成功!');

}catch{

    console.log('写入失败!');

}

4、异步方式读取文件

异步方式读取文件,采用的都是回调函数的形式,相比较同步方式,代码量变复杂了。优势是,可以同时操作多个文件。

(1)读取文件 open/read/close

//01.打开文件

fs.open('./file/a.txt',(err,fd)=>{

 //回调函数的两个参数分别是:错误信息,文件标识,如果能够打开文件,错误信息为null

if(!err){

 //02.读取文件中的内容

fs.read(fd,(err,num,buf)=>{

//回调函数的三个参数分别是:错误信息,读取文件的字节数,buffer内容

if(!err){

console.log('读取了'+num+'个字节');

console.log('内容是:'+buf.toString());

            }

 //03.文件读取结束后,需要关闭文件

fs.close(fd,(err)=>{

if(!err){

                    console.log('文件读取完毕!');

                }

            })

        })

    }

})

(2)一般方式读取文件 readFile()

方法内部,帮我们完成了文件的打开,读取,关闭操作。

fs.readFile('./file/a.txt',(err,buf)=>{

if(!err){

console.log('异步:'+buf.toString());

    }

})

5、异步方式写入文件

(1)写入文件 open/read/close

// 01.打开文件

// 参数1:文件位置

// 参数2:打开文件的方式,r是读,w是写,a是追加

fs.open('./file/b.txt','a',(err,fd)=>{

if(!err){

 // 02.向文件中写入内容

fs.write(fd,'HelloWorld',(err)=>{

if(!err){

 // 03.文件写入后,需要关闭文件

fs.close(fd,(err)=>{

if(!err){

                        console.log('写入成功!');

                    }

                })

            }

        })

    }

})

(2)一般方式写入文件 writeFile()

fs.writeFile('./file/b.txt','HelloWorld',{flag:'a'},(err)=>{

if(!err){

        console.log('异步:写入成功!');

    }

})

九、try..catch

将可能会发生异常的代码放在try中,如果程序发生异常,会跳转到catch中执行保护代码,

使程序不至于就此终止。catch代码块可以传递一个参数e,里面保存的是发生异常的消息。

// 文件系统在实际开发中的用法:

try{

    let num1 = 10

    let num3 = num1 + num4

    console.log(num3);

}catch(e){

 //通常情况下,需要将错误信息写入到日志文件中

 // console.log('上面的代码发生了错误',e.message);

fs.writeFile('./file/log.txt',e.message+' 发生时间:'+(new Date())+'\r\n',{flag:'a'},(err)=>{

if(!err){

            console.log('错误信息,写入日志文件');

        }

    })

}

十、同步API和异步API

1、同步API

同步API:只有当前API执行完成后,才能继续执行下一个API。

同步API,可以通过返回值接收结果。

//同步API

function fun1(){

    return '大家好!我是一个同步方法'

}

//同步API,可以通过返回值接收结果

let str1 = fun1()

console.log(str1);// str1

2、异步API

异步API:当前API的执行不会阻塞后续代码的执行。

异步API时,直接写一个回调函数作为参数传进入,这个函数接收异步API返回值。

//异步API

function fun2(callback){

    setTimeout(() => {

        callback('大家好!我是一个异步方法')

    }, 1000);

}

//调用异步API时,直接写一个回调函数作为参数传进入

//回调函数,通常会写成箭头函数

fun2(str => console.log(str))

十一、Promise 对象

1、语法

ES6推出了一个全新的对象:Promise,该对象用于处理回调地狱。

Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。

Promise对象的then()方法用来获取成功的返回结果;catch()方法用来获取失败的返回结果。

function myReadFile(path) {

return new Promise((resolve) => {

fs.readFile(path, (errr) => {

if (!err) {

resolve(r.toString())

            }

        })

    })

}

myReadFile('./file/a.txt').then(r=> {

if (r== '中国') {

        return myReadFile('./file/e.txt')

    }

}).then(r=> {

if (r== '赛虹桥街道') {

console.log(r);

    }

})

2、async和await

async关键字,用于定义异步函数,异步函数中,可以使用await关键字,简化then的步骤。await关键字提取Promise对象的返回的结果。

async function run() {

    let a = await myReadFile('./file/a.txt')

    if (a != '中国') return

    let e = await myReadFile('./file/e.txt')

    if (e != '赛虹桥街道') return

    console.log(e);

}

run()

十二、MongoDB数据库

1、数据库下载安装

使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose。

使用npm install mongoose命令下载。

2、启动MongoDB

运行net start mongoDB即可启动MongoDB,否则MongoDB将无法连接。

[if !supportLists]3、[endif]导入mongoose和数据库连接

使用mongoose提供的connect方法连接数据库。注意:如果连接的数据库(MySchool)不存在,会自动创建数据库(MySchool)。

// 导入mongoose

let mongoose = require('mongoose')

// 连接数据

mongoose.connect('mongodb://localhost/MySchool',

{ useNewUrlParser: true,useUnifiedTopology: true })

.then(() => console.log('数据库连接成功'))

.catch(err=> console.log('数据库连接失败', err));

4、创建表

(1)定义表规则

定义表规则:表里面的有哪些列,分别是什么数据类型。

① 基本写法

// 定义student表规则

const studentSchema = new mongoose.Schema({

 //定义具体的表规则

    name: String,

    age: Number,

    sex:String,

    hobbies:[String],

    isVip: Boolean

});

② 定义表里具体属性的规范

在创建集合规则时,可以设置当前字段的验证规则,验证失败就输入插入失败。

required: true    必传字段

minlength:3    字符串最小长度

maxlength: 20   字符串最大长度

min: 2    数值最小为2

max: 100    数值最大为100

enum: ['html', 'css', 'javascript', 'node.js']

trim: true    去除字符串两边的空格

validate: 自定义验证器

default: 默认值

let studentSchema = new mongoose.Schema({

 //name属性的规范

    name:{

type:String,// 类型是String

require:true,// 不允许为空

minlength:2,// 最小长度为2

maxlength:8// 最大长度为8

    },

    sex:{

        type:String,

default:'男'// 性别的默认值是“男”

    },

    age:{

        type:Number,   

min:3,// 年龄的范围是3-100

        max:100

    },

    hobbies:{

        type:[String], 

require:false// 爱好允许为空

    }

})

(2)创建表对象

注意:数据库中的表名会自动改成复数格式(students)

const Student = mongoose.model('Student', studentSchema)

[if !supportLists]5、[endif]向表中添加数据

方法(1) 通过表实例对象

① 创建表实例对象

// 5.1.

const stu1 = new Student({

    name: '张三',

    age: 20,

    sex: '男',

    hobbies: ['学习','睡觉','打球'],

    isVip:true

});

② 表实例对象通过save方法将数据保存到数据库的数据表中

stu1.save((err,result)=>{

    if(!err){

 //添加成功,打印添加的结果

        console.log(result);

    }

})

方法(2) create方法,通过回调函数返回结果

通过数据表的create的方法,直接向数据表中添加数据(通过回调函数返回结果)。

Student.create({

    name: '李四',

    age: 22,

    sex: '女',

    hobbies: ['看电视','睡觉','看电影'],

    isVip:false

},(err,result)=>{

if(!err){

console.log(result);

    }

})

方法(3) create方法,通过Promise对象返回结果

通过数据表的create的方法,直接向数据表中添加数据(通过Promise对象返回结果)。

Student.create({

    name: '王五',

    age: 24,

    sex: '男',

    hobbies: ['敲代码','睡觉','写字'],

    isVip:true

}).then(result=>{

console.log(result);

}).catch(err=>{

console.log(err);

})

6、查询语句

(1)查询全部信息find()

find方法返回的是数组。

// 查询student表的全部数据

Student.find().then(r=>{

    console.log(r);

})

(2)根据条件查询find(条件)

返回的是符合条件的数组。如果没有满足条件的结果,就返回一个空数组。

Student.find({name:'李白'}).then(r=>{

    console.log(r);

})

(3)返回表中的第一个对象findOne()

findOne方法返回的是对象。

Student.findOne().then(r=>{

console.log(r);

})

(4)根据条件查询 findOne(条件)

查询第一个满足条件的,返回的是对象,如果没有满足条件的结果,就返回null。

Student.findOne({name:'李白'}).then(r=>{

    console.log(r);

})

(5)查询某个范围内的数据

① 查询大于某数值的数据 $gt

// 查询年龄于20岁的学生信息

Student.find({age:{$gt:20}}).then(r=>{

console.log(r);

})

② 查询大于某数值的数据 $lt

// 查询年龄小于20岁的学生信息

Student.find({age:{$lt:20}}).then(r=>{

console.log(r);

})

③ 查询两数之间的数据 {$gt:num1,$lt:num2}}

// 查询年龄在20岁到40岁之间的学生信息

Student.find({age:{$gt:20,$lt:40}}).then(r=>{

console.log(r);

})

④ 查询两数之间的数据(包括两数) {$gte:num1,$lte:num2}}

// 查询年龄在20岁到40岁之间的学生信息(包括20和40)

Student.find({age:{$gte:20,$lte:40}}).then(r=>{

console.log(r);

})

(6)根据正则表达式匹配查询条件(用于模糊查询)

$regex 正则,用于模糊查询。

select方法,筛选查询列。注意:_id列默认会返回,如果不需要查询id,就加上-_id。

// 查询姓名中包含'刘'的学生信息,只返回name、sex、age列

Student.find({name:{$regex:/刘/i}}).select('name sex age -_id').then(r=>{

    console.log(r);

})

注意:如果正则条件是模板字符串,需要使用new RegExp()创建。

Student.find({ name: { $regex: new RegExp(`${name}`, 'i') } }).then(r=> {res.send(r)})

(7)匹配包含

① $in 满足其中一个元素的数据

 // 查询爱好中包含‘睡觉’或‘学习’的学生信息

Student.find({hobbies:{$in:['睡觉','学习']}}).select('name sex age hobbies -_id').then(r=>{

    console.log(r);

})

② $all 满足所有元素的数据

// 查询爱好中包含‘睡觉’和‘学习’的学生信息

Student.find({hobbies:{$all:['睡觉','学习']}}).select('name sex age hobbies -_id').then(r=>{

console.log(r);

})

(8)对查询结果排序sort()

① 升序排列

// 根据年龄升序查询学生信息

Student.find().sort('age').select('name sex age -_id').then(r=>{

    console.log(r);

})

② 降序排列

// 根据年龄降序查询学生信息

Student.find().sort('-age').select('name sex age -_id').then(r=>{

    console.log(r);

})

③ 根据性别升序,再根据年龄降序

// 先返回相同性别的学生,相同性别的学生再根据年龄降序

Student.find().sort('sex -age').select('name sex age -_id').then(r=>{

    console.log(r);

})

(9)分页查询

skip()跳过多少条数据;limit()限制查询数量。

// 每页2条数据,显示第2页

let pageIndex = 2//定义页码

let pageSize = 2//定义每页数量

Student.find().skip((pageIndex-1)*pageSize).limit(pageSize).select('name sex age -_id').then(r=>{

console.log(r);

})

(10)修改指定对象的信息

① 修改单个对象 updateOne()

updateOne({查询条件}, {要修改的值})

Student.updateOne({_id:'617f5d951df9a826303015fa'},{name:'张飞',age:38}).then(r=>{

console.log(r);

})

② 修改多个对象 updateMany()

updateMany({查询条件}, {要更改的值})

Student.updateMany({sex:'女'},{age:25}).then(r=>{

    console.log(r);

})

(11)删除数据

① 删除单个 findOneAndDelete()

删除成功后,返回删除的对象

Student.findOneAndDelete({ _id: '617f5d951df9a826303015fa' }).then(r=> {

    console.log(r)

})

② 删除单个 deleteOne()

删除成功后,返回删除的数量

Student.deleteOne({ _id: '617f5d951df9a826303015fc' }).then(r=> {

    console.log(r)

})

③ 删除多个 deleteMany()

删除成功后,返回删除的数量

Student.deleteMany({sex:'女'}).then(r=>{

console.log(r);

})

十三、Express框架

1、定义

Express是一个基于Node平台的web应用开发框架,它提供了一系列的强大特性,帮助你创建各种Web应用。

使用npm install express 命令进行下载。

2、基本步骤

(1)导入express

let express = require('express')

(2)通过express函数,创建并返回一个web服务器对象

let app = express()

(3)启动服务器,并监听一个端口号(端口号是自定义的)

app.listen(8848,()=>{

    console.log('服务器成功开启,端口号是8848');

})

3、中间件

(1)定义

中间件就是一堆方法,可以接收客户端发来的请求、可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理。

(2)app.use中间件用法

app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求。所有的请求,都会先走use,作用是拦截器。

实际开发中,我们用use中间件方法里面去判断用户的权限,从而确定该用户能否继续请求相关的接口。

app.use((req,res,next)=>{

 //表示:允许跨域请求

 res.setHeader('Access-Control-Allow-Origin','*')

 //next方法,表示继续往下执行

    next()

})

4、跨域

(1)定义

同源策略:协议名,主机名(域名或ip地址),端口号必须完全相同。违背同源策略就是跨域。

ajax请求,必须要遵循同源策略。

(1)解决跨域

设置响应头,允许跨域请求。

 response.setHeader('Access-Control-Allow-Origin','*')

(2)允许自定义请求头信息

响应头*表示所有类型的头信息都可以接受。

 response.setHeader('Access-Control-Allow-Headers','*')

5、get请求接口

(1)get请求参数的获取

req.query接收前端传递的GET请求参数,框架内部会将GET参数转换为对象并返回。

(2)定义get请求接口

req是请求对象,里面保存的是客户端传过来的请求参数。

res是响应对象,用于给客户端响应结果。

res.send()将结果返回给前端。

app.get('/getStudents',(req,res)=>{

 res.send('hello')

})

6、post请求接口

(1)post请求参数的获取

req.body接收前端传递过来的POST请求参数。

接收POST请求参数,服务器需要进行设置。

通过express.json()中间件,解析表单中的JSON格式数据。

通过express.urlencoded()中间件,解析表单中的url-encoded格式数据。

// 设置允许接收json格式的数据({"name":"张三","age":20})

app.use(express.json())

// 设置允许接收urlencoded格式的数据("name=张三&age=20")

app.use(express.urlencoded({extended:false}))

(2)定义post请求接口

app.post('/add', (reqres) => {

console.log(req.body);// 接收请求参数

 res.send('hello')

})

十四、AJAX

1、原生AJAX

(1)GET请求

GET请求的参数,使用?直接拼接在url地址后面,如果有多个参数使用&符号。

参数例如:name=${name}&pageIndex=${pageIndex}

// 01.创建xhr对象

let xhr = new XMLHttpRequest()

// 02.初始化请求

xhr.open('GET',`http://localhost:5566/students?name=${name}`)

// 03.发送请求

xhr.send()

// 04.监听事件,并接收结果

xhr.onreadystatechange = function(){

//请求完成

     if(xhr.readyState===4){

//请求成功

         if(xhr.status===200){     

console.log(xhr.response);//打印响应结果

         }

     }

 }

(2)POST请求

① 设置Content-Type请求头

POST请求时,需要设置Content-Type请求头,告诉服务器传递的数据格式。

如果是urlencoded格式的数据:

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")

如果是json字符串格式的数据:

xhr.setRequestHeader('Content-Type','application/json')

② 参数传递

post请求的参数,在发送时传递。

传递urlencoded格式的数据:

xhr.send(`name=polo&age=35`)

传递json字符串格式的数据:

let params = {

     name:name,

hobbies:hobbies.split(',')//爱好,转为数组

 }

xhr.send(JSON.stringify(params))// 将对象转为json格式字符串

③ 基本格式

  let xhr = new XMLHttpRequest()

  xhr.open('POST','http://localhost:5566/deleteStudent')

  xhr.setRequestHeader('Content-Type','application/json')

xhr.send(JSON.stringify({_id:id}))

  xhr.onreadystatechange = function(){

      if(xhr.readyState===4){

          if(xhr.status===200){

                console.log(xhr.response);

          }

      }

}

[if !supportLists]2、[endif]jQuery AJAX

[if !supportLists](1)[endif]GET请求

$.get(请求地址, {参数名: 参数值}, 回调函数)

$.get('http://localhost:5566/students',{name:"张三"},r=>{

console.log(r);// r表示请求成功时返回的结果数据

  })

[if !supportLists](2)[endif]POST请求

$.post(请求地址, {参数名: 参数值}, 回调函数)

$.post('http://localhost:5566/deleteStudent',{_id:id},r=>{

console.log(r);// r表示请求成功时返回的结果数据

  })

[if !supportLists](3)[endif]通用型方法ajax

① get请求

            $.ajax({

type: "get",// 请求的接口地址

url: url,// 请求方式get 或 post

dataType: "json", // 返回的数据类型

 // 请求成功后的回调函数

success: function (r) {

console.log(r)

                },

 // 请求失败后调用的函数

error: function (err) {

                    console.log('请求错误')

                }

            });

② post请求

发送post请求时,如果请求参数是json字符串格式,需要设置contentType请求头为'application/json'。contentType默认值 "application/x-www-form-urlencoded"。

let params = {

         name:name,

         hobbies:hobbies.split(',')

   }

$.ajax({

url:url,// 请求的接口地址

type:'POST',// 请求方式get 或 post

data:JSON.stringify(params),// 请求的参数

         contentType:'application/json',

success:function(r){

console.log(r);// r表示请求成功时返回的结果数据

         }

    })

3、axios AJAX

(1)引入axios库

src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js">

(2)GET请求

① get请求的参数可以直接用?拼接在URL中。

axios.get('/user?ID=12345').then(function (response) {

console.log(response);

}).catch(function (error) {

console.log(error);

        });

② get请求的参数可以写在params对象中。

注意:get请求的返回结果包含很多信息,需要将结果中的data解构出来。data中存放的才是需要的数据。

      axios.get('http://localhost:5566/students', {

            params: {

               name:name

           }

}).then(({ data}) => {

           console.log(data)

      })

(3)POST请求

post请求参数直接写在对象中传入。

let params = {

         name:name,

         hobbies:hobbies.split(',')

 }

axios.post(`http://localhost:5566/deleteStudent`, params ).then(({ data}) => {

         console.log(data)

})

(4)通用方式axios

            axios({     

method: 'POST',//请求方法

url: '/axios-server',//url

params: {//请求参数

                    vip: 10,

                    level: 30

                },          

headers: {//设置请求头信息

                    a: 100,

                    b: 200

                },

 //请求体参数

                data: {

                    username: 'admin',

                    password: 'admin'

                }

}).then(response=> {

console.log(response);

 //响应状态码

console.log(response.status);

 //响应状态字符串

console.log(response.statusText);

 //响应头信息

console.log(response.headers);

 //响应体

console.log(response.data);

            })

4、fetchAJAX

1)fetch定义

fetch是一个浏览器内置的全新的请求API。之前我们使用的jquery和axios的请求方法只是对XMLHttpRequest对象的封装。

fetch()函数的第一个参数是url地址,第二个参数是配置对象。

(2)GET请求

GET请求的参数,使用?直接拼接在url地址后面,如果有多个参数使用&符号。

fetch(`http://localhost:5566/students?stuName=${stuName}`,{

method:'GET',//设置请求方式(默认是GET)

}).then(response=>{

 // 第一个then,用于返回请求的状态信息(检查请求是否成功等等)

 // 再通过请求状态对象的.json()方法,返回请求结果

returnresponse.json()

}).then(=>{

console.log(r)// 返回请求结果

 })

(3)POST请求

发送post请求时,请求参数如果是json字符串格式,需要配置请求头headers,设置Content-Type为'application/json'。

            let params = {

                name:name,

                hobbies:hobbies.split(','),

            }

            fetch(url,{

                method:'POST',

 //配置请求头信息

                headers:{

                    'Content-Type':'application/json'

                },

body:JSON.stringify(params)// post请求参数

}).then(r=>{

returnr.json()

}).then(r=>{

console.log(r)// 返回请求结果

            })

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 一、文件/文件夹管理 ls 列出当前目录文件(不包括隐含文件)ls -a 列出当前目录文件(包括隐含文件)ls -...
    BerL1n阅读 7,668评论 0 79
  • 完全没想到这篇文章的阅读量有点多,之前没有考虑什么就直接发布了,对此表示歉意,所以重新找了一篇文章汇总,以免在坑到...
    BabyFatXu阅读 1,672评论 0 1
  • 一、linux简介 linux 系统可以用 Windows 系统来做一个类比,操作系统都是由一堆文件构成的。在wi...
    jinghenggl阅读 472评论 0 0
  • Windows系统 WIN+R打开运行输入cmd即可进入命令行,也可以通过cmd /c 命令 和 cmd /k 命...
    云间一壶酒阅读 249评论 0 0
  • 一. 命令基本格式 1. 含义: [seal@localhost ~]$ 其中seal为用户名称(即用户名),ro...
    AE86过弯不刹车阅读 264评论 0 0