nodejs

一、cmd終端常用命令

1、dir ?????????顯示目錄里面的所有文件(包括文件夾和文件)

2、cd.. ????????回到上一級目錄

3、cd\ ?????????回到根目錄

4、cd 路徑 ?????跳轉(zhuǎn)到指定的目錄(路徑可以是絕對路徑,也可以是相對路徑)

相對路徑是相當(dāng)于當(dāng)前路徑的路徑;絕對路徑是相對于當(dāng)前盤符根路徑的路徑。

5、盤符名稱: ???切換盤符(比如:d:,回車后就會切換到d盤)

6、cls ?????????清屏(清空屏幕)

7、md 目錄名稱 ?創(chuàng)建目錄

8、rd 目錄名稱 ?刪除空目錄

9、del 文件名 ??刪除指定的文件

10、del 目錄名 ?刪除目錄里面的全部文件

11、copy 命令用于復(fù)制文件

12、move 命令用于移動文件


打開當(dāng)前目錄里面的文件或程序:文件名.擴(kuò)展名 回車

我們在cmd窗口中,輸入文件名.擴(kuò)展名 回車,首先它會在當(dāng)前目錄中找該文件是否存在,存在則打開該文件。如果當(dāng)前目錄中沒有這個文件,就會到系統(tǒng)變量的path中,遍歷所有的路徑,找這個文件是否存在,存在則打開文件;如果還是沒有,則報錯。

二、模塊

js程序不能直接運(yùn)行,必須要在瀏覽器中運(yùn)行;在網(wǎng)頁中引入js程序時,一定要注意引入的順序,因為前后js可能是有關(guān)系的。綜上,引入nodejs解決問題。

在nodejs環(huán)境中,每一個獨(dú)立的js文件,就是一個獨(dú)立模塊。

每個獨(dú)立的模塊是一個私有的作用域,每一個獨(dú)立模塊其實(shí)就是獨(dú)立方法。這個方法,提供了5個參數(shù):exports, require, module, __filename, __dirname。

1、exports對象

nodejs中,導(dǎo)出當(dāng)前模塊的成員,可以用exports,也可以用module.exports。其實(shí)exports對象,指向了module.exports對象,最終導(dǎo)出的是module.exports對象。

通常情況下exports

(1)使用exports對象導(dǎo)出

exports導(dǎo)出成員時,不能重新給exports賦值一個新對象,只能一個一個導(dǎo)出。

let?money =?10000

let?city =?'南京'

exports.money =?money

exports.city =?city

注意:不能采用下面的方式導(dǎo)出成員

?exports?=?{

? ? money:money,

? ? city:city

}

(2)使用module.exports

module.exports導(dǎo)出成員時,既可以一個一個導(dǎo)出,也可以通過賦值一個對象的方式導(dǎo)出。

module.exports.fun1?=?fun1

module.exports?=?{

? ? money:money,

? ? city:city,

? ? fun1:fun1

}

2、require方法

用于導(dǎo)入其他模塊里面的成員。

在nodejs中,通過require方法,導(dǎo)入其他模塊。一般情況下,我們會通過解構(gòu)賦值的方式,直接從導(dǎo)入的對象中獲取需要的成員。

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

3、module對象

是當(dāng)前模塊本身,它里面的exports對象屬性,也是用于導(dǎo)出當(dāng)前模塊里面的成員。

4、__filename變量

返回當(dāng)前模塊文件的絕對路徑。

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

5、__dirname變量

返回當(dāng)前模塊文件所在目錄的絕對路徑。

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

三、通過require導(dǎo)入模塊

1、require()

require方法,用于導(dǎo)入模塊,方法的參數(shù)是:模塊的標(biāo)識。

導(dǎo)入模塊時,模塊標(biāo)識如果沒有文件的后綴名,

(1)首先判斷該模塊是不是系統(tǒng)模塊

(2)如果不是系統(tǒng)模塊,再判斷是不是第三方模塊

(3)如果導(dǎo)入的是自定義包里面的模塊,可以省略包里面的具體的文件

// 表示導(dǎo)入自定義math包里的模塊,默認(rèn)是math包里的index.js文件

let?math?=?require('./math')??

2、系統(tǒng)模塊

通過系統(tǒng)模塊的名稱導(dǎo)入。

let?path?=?require('path')

3、第三方模塊

通過模塊的名稱導(dǎo)入(這個名稱是package.json文件中name屬性對應(yīng)的名稱)。

let?math?=?require('math')

4、自定義模塊

通過模塊的路徑導(dǎo)入,路徑可以是相對路徑,也可以是絕對路徑。

四、global

在node環(huán)境中,沒有window對象。有一個全局對象global,類似于瀏覽器環(huán)境中的window對象。

五、npm

(1)下載包

備注:install的簡寫是i,--save的簡寫是-S,--save-dev的簡寫是-D,--global的簡寫-g。

npm install 包名 ??????????????下載包 (默認(rèn)會將下載的包添加到生產(chǎn)環(huán)境依賴,生產(chǎn)環(huán)境依賴的包參與本項目的打包)

npm install 包名 --save ???????(--save表示下載包,并添加到生產(chǎn)環(huán)境依賴)

npm install 包名 --save-dev ???(--save-dev表示下載包,并添加到開發(fā)環(huán)境依賴,只是開發(fā)時依賴該包,不參與本項目的打包)

npm install 包名 --global ?????安裝全局插件

使用npm下載第三方包后,會在項目根路徑中添加一個package-lock.json文件。該文件是可以刪除的,它的作用是記錄第三方包的完整信息,方便下次下載包時快速定位該包的信息,省去了查找包的時間。

(2)升級包

npm update 包名 ???????????????對指定包進(jìn)行升級

npm update ????????????????????升級所有包

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

備注:remove的簡寫是r

npm remove 包名 ???????????????移除包

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

(4)下載所有依賴包

npm install/i ????????根據(jù)package.json文件中的依賴關(guān)系,下載當(dāng)前項目所依賴的包

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一樣。(唯一的區(qū)別是:cnpm install 包名,不會將下載的包默認(rèn)添加到生產(chǎn)環(huán)境依賴。必須要加上--save。)

5、安裝nodemon工具

nodemon是一種工具,可以自動監(jiān)測文件的變化,當(dāng)有變化時重新啟動服務(wù)。(需要使用nodemon時,先關(guān)閉自動保存)

npm i nodemon -g ?????全局安裝nodemon

nodemon ./index.js運(yùn)行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可以省略,因為默認(rèn)就是添加到生產(chǎn)依賴。

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

七、系統(tǒng)模塊path

1、定義

系統(tǒng)模塊path,用于操作路徑相關(guān)。

let?path?=?require('path')

2、join() 路徑拼接

path.join('路徑','路徑',...) ??該方法會根據(jù)當(dāng)前nodejs所在的系統(tǒng)環(huán)境,返回正確格式的拼接路徑。

不同的操作系統(tǒng),路徑的拼接符是不一樣的。windows系統(tǒng)中,路徑的拼接符是 / 或 \ ;linux系統(tǒng)中,路徑的拼接符是 / ;我們用nodeJS開發(fā)的程序,將來部署到什么操作系統(tǒng)的服務(wù)器上是不確定的。所以,使用join()方法,返回拼接路徑。

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

3、resolve()

帶參數(shù),path.resolve(相對路徑)方法,返回一個相對路徑的絕對路徑。

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

不帶參數(shù),path.resolve()方法,返回當(dāng)前模塊所在目錄的絕對路徑。

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

全局變量__dirname,也是返回當(dāng)前模塊所在目錄的絕對路徑

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

4、返回指定包(math)的絕對路徑

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

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

七、系統(tǒng)模塊path

1、定義

系統(tǒng)模塊path,用于操作路徑相關(guān)。

let?path?=?require('path')

2、join() 路徑拼接

path.join('路徑','路徑',...) ??該方法會根據(jù)當(dāng)前nodejs所在的系統(tǒng)環(huán)境,返回正確格式的拼接路徑。

不同的操作系統(tǒng),路徑的拼接符是不一樣的。windows系統(tǒng)中,路徑的拼接符是 / 或 \ ;linux系統(tǒng)中,路徑的拼接符是 / ;我們用nodeJS開發(fā)的程序,將來部署到什么操作系統(tǒng)的服務(wù)器上是不確定的。所以,使用join()方法,返回拼接路徑。

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

3、resolve()

帶參數(shù),path.resolve(相對路徑)方法,返回一個相對路徑的絕對路徑。

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

不帶參數(shù),path.resolve()方法,返回當(dāng)前模塊所在目錄的絕對路徑。

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

全局變量__dirname,也是返回當(dāng)前模塊所在目錄的絕對路徑

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

4、返回指定包(math)的絕對路徑

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

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

八、系統(tǒng)模塊fs

1、定義

系統(tǒng)模塊fs,用于操作文件相關(guān)。

let?fs?=?require('fs')

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

同步方式讀取文件,指的是文件的讀取過程必須是一個一個讀取。假如,后面還要讀取其他文件,必須要等到前面的文件讀取完成了,再讀取下一個文件。

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

① 打開文件,通過openSync方法打開文件,返回值是文件標(biāo)識(文件標(biāo)識是一個數(shù)字)

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

② 讀取文件中的內(nèi)容,通過readSync方法讀取文件。

參數(shù)1:文件標(biāo)識

參數(shù)2:buffer容器

創(chuàng)建一個buffer容器,用于接收讀取到的數(shù)據(jù),其實(shí)就是開辟一段內(nèi)存空間(單位是字節(jié))。注意:一個漢字占用三個字節(jié)空間。

let?buf?=?Buffer.alloc(30)// 創(chuàng)建30字節(jié)的buffer容器

fs.readSync(fd,buf)// 用buf接收fd文件數(shù)據(jù)

③ 文件讀取結(jié)束后,需要關(guān)閉文件。

fs.closeSync(fd)// 關(guān)閉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方法打開文件,返回值是文件標(biāo)識(文件標(biāo)識是一個數(shù)字)

參數(shù)1:文件路徑,

參數(shù)2:打開文件的方式:r是讀,w是寫,a是追加。

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

② 向文件中寫入內(nèi)容(如果需要寫入中文,加一個'utf-8';內(nèi)容是純英文可以省略)

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

fs.writeSync(fd,'HelloWorld')

③ 文件寫入后,需要關(guān)閉文件

fs.closeSync(fd)

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

writeFileSync()方法內(nèi)部已經(jīng)完成了文件的打開、讀取、關(guān)閉操作。

try{

? ? fs.writeFileSync('./file/a.txt','HelloWorld',{flag:'a'})// 追加參數(shù)a要寫在對象中

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

}catch{

? ? console.log('寫入失??!');

}

4、異步方式讀取文件

異步方式讀取文件,采用的都是回調(diào)函數(shù)的形式,相比較同步方式,代碼量變復(fù)雜了。優(yōu)勢是,可以同時操作多個文件。

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

//01.打開文件

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

?//回調(diào)函數(shù)的兩個參數(shù)分別是:錯誤信息,文件標(biāo)識,如果能夠打開文件,錯誤信息為null

if(!err){

?//02.讀取文件中的內(nèi)容

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

//回調(diào)函數(shù)的三個參數(shù)分別是:錯誤信息,讀取文件的字節(jié)數(shù),buffer內(nèi)容

if(!err){

console.log('讀取了'+num+'個字節(jié)');

console.log('內(nèi)容是:'+buf.toString());

? ? ? ? ? ? }

?//03.文件讀取結(jié)束后,需要關(guān)閉文件

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

if(!err){

? ? ? ? ? ? ? ? ? ? console.log('文件讀取完畢!');

? ? ? ? ? ? ? ? }

? ? ? ? ? ? })

? ? ? ? })

? ? }

})

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

方法內(nèi)部,幫我們完成了文件的打開,讀取,關(guān)閉操作。

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

if(!err){

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

? ? }

})

5、異步方式寫入文件

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

// 01.打開文件

// 參數(shù)1:文件位置

// 參數(shù)2:打開文件的方式,r是讀,w是寫,a是追加

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

if(!err){

?// 02.向文件中寫入內(nèi)容

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

if(!err){

?// 03.文件寫入后,需要關(guān)閉文件

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

將可能會發(fā)生異常的代碼放在try中,如果程序發(fā)生異常,會跳轉(zhuǎn)到catch中執(zhí)行保護(hù)代碼,

使程序不至于就此終止。catch代碼塊可以傳遞一個參數(shù)e,里面保存的是發(fā)生異常的消息。

// 文件系統(tǒng)在實(shí)際開發(fā)中的用法:

try{

? ? let?num1?=?10

? ? let?num3?=?num1?+?num4

? ? console.log(num3);

}catch(e){

?//通常情況下,需要將錯誤信息寫入到日志文件中

?// console.log('上面的代碼發(fā)生了錯誤',e.message);

fs.writeFile('./file/log.txt',e.message+' 發(fā)生時間:'+(new?Date())+'\r\n',{flag:'a'},(err)=>{

if(!err){

? ? ? ? ? ? console.log('錯誤信息,寫入日志文件');

? ? ? ? }

? ? })

}

十、同步API和異步API

1、同步API

同步API:只有當(dāng)前API執(zhí)行完成后,才能繼續(xù)執(zhí)行下一個API。

同步API,可以通過返回值接收結(jié)果。

//同步API

function?fun1(){

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

}

//同步API,可以通過返回值接收結(jié)果

let?str1?=?fun1()

console.log(str1);// str1

2、異步API

異步API:當(dāng)前API的執(zhí)行不會阻塞后續(xù)代碼的執(zhí)行。

異步API時,直接寫一個回調(diào)函數(shù)作為參數(shù)傳進(jìn)入,這個函數(shù)接收異步API返回值。

//異步API

function?fun2(callback){

? ? setTimeout(() =>?{

? ? ? ? callback('大家好!我是一個異步方法')

? ? }, 1000);

}

//調(diào)用異步API時,直接寫一個回調(diào)函數(shù)作為參數(shù)傳進(jìn)入。

//回調(diào)函數(shù),通常會寫成箭頭函數(shù)

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

十一、Promise 對象

1、語法

ES6推出了一個全新的對象:Promise,該對象用于處理回調(diào)地獄。

Promise的構(gòu)造函數(shù)接收一個參數(shù),是函數(shù),并且傳入兩個參數(shù):resolve,reject,分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。

Promise對象的then()方法用來獲取成功的返回結(jié)果;catch()方法用來獲取失敗的返回結(jié)果。

function?myReadFile(path) {

return?new?Promise((resolve) =>?{

fs.readFile(path, (err,?r) =>?{

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關(guān)鍵字,用于定義異步函數(shù),異步函數(shù)中,可以使用await關(guān)鍵字,簡化then的步驟。await關(guān)鍵字提取Promise對象的返回的結(jié)果。

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數(shù)據(jù)庫

1、數(shù)據(jù)庫下載安裝

使用Node.js操作MongoDB數(shù)據(jù)庫需要依賴Node.js第三方包mongoose。

使用npm install mongoose命令下載。

2、啟動MongoDB

運(yùn)行net start mongoDB即可啟動MongoDB,否則MongoDB將無法連接。

[if !supportLists]3、[endif]導(dǎo)入mongoose和數(shù)據(jù)庫連接

使用mongoose提供的connect方法連接數(shù)據(jù)庫。注意:如果連接的數(shù)據(jù)庫(MySchool)不存在,會自動創(chuàng)建數(shù)據(jù)庫(MySchool)。

// 導(dǎo)入mongoose

let?mongoose?=?require('mongoose')

// 連接數(shù)據(jù)

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

{ useNewUrlParser:?true,useUnifiedTopology:?true?})

.then(() =>?console.log('數(shù)據(jù)庫連接成功'))

.catch(err=>?console.log('數(shù)據(jù)庫連接失敗',?err));

4、創(chuàng)建表

(1)定義表規(guī)則

定義表規(guī)則:表里面的有哪些列,分別是什么數(shù)據(jù)類型。

① 基本寫法

// 定義student表規(guī)則

const?studentSchema?=?new?mongoose.Schema({

?//定義具體的表規(guī)則

? ? name:?String,

? ? age:?Number,

? ? sex:String,

? ? hobbies:[String],

? ? isVip:?Boolean

});

② 定義表里具體屬性的規(guī)范

在創(chuàng)建集合規(guī)則時,可以設(shè)置當(dāng)前字段的驗證規(guī)則,驗證失敗就輸入插入失敗。

required: true ???必傳字段

minlength:3 ???字符串最小長度

maxlength: 20 ??字符串最大長度

min: 2 ???數(shù)值最小為2

max: 100 ???數(shù)值最大為100

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

trim: true ???去除字符串兩邊的空格

validate: 自定義驗證器

default: 默認(rèn)值

let?studentSchema?=?new?mongoose.Schema({

?//name屬性的規(guī)范

? ? name:{

type:String,// 類型是String

require:true,// 不允許為空

minlength:2,// 最小長度為2

maxlength:8// 最大長度為8

? ? },

? ? sex:{

? ? ? ? type:String,

default:'男'// 性別的默認(rèn)值是“男”

? ? },

? ? age:{

? ? ? ? type:Number,? ?

min:3,// 年齡的范圍是3-100

? ? ? ? max:100

? ? },

? ? hobbies:{

? ? ? ? type:[String],?

require:false// 愛好允許為空

? ? }

})

(2)創(chuàng)建表對象

注意:數(shù)據(jù)庫中的表名會自動改成復(fù)數(shù)格式(students)

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

[if !supportLists]5、[endif]向表中添加數(shù)據(jù)

方法(1) 通過表實(shí)例對象

① 創(chuàng)建表實(shí)例對象

// 5.1.

const?stu1?=?new?Student({

? ? name:?'張三',

? ? age:?20,

? ? sex:?'男',

? ? hobbies:?['學(xué)習(xí)','睡覺','打球'],

? ? isVip:true

});

② 表實(shí)例對象通過save方法將數(shù)據(jù)保存到數(shù)據(jù)庫的數(shù)據(jù)表中

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

? ? if(!err){

?//添加成功,打印添加的結(jié)果

? ? ? ? console.log(result);

? ? }

})

方法(2) create方法,通過回調(diào)函數(shù)返回結(jié)果

通過數(shù)據(jù)表的create的方法,直接向數(shù)據(jù)表中添加數(shù)據(jù)(通過回調(diào)函數(shù)返回結(jié)果)。

Student.create({

? ? name:?'李四',

? ? age:?22,

? ? sex:?'女',

? ? hobbies:?['看電視','睡覺','看電影'],

? ? isVip:false

},(err,result)=>{

if(!err){

console.log(result);

? ? }

})

方法(3) create方法,通過Promise對象返回結(jié)果

通過數(shù)據(jù)表的create的方法,直接向數(shù)據(jù)表中添加數(shù)據(jù)(通過Promise對象返回結(jié)果)。

Student.create({

? ? name:?'王五',

? ? age:?24,

? ? sex:?'男',

? ? hobbies:?['敲代碼','睡覺','寫字'],

? ? isVip:true

}).then(result=>{

console.log(result);

}).catch(err=>{

console.log(err);

})

6、查詢語句

(1)查詢?nèi)啃畔ind()

find方法返回的是數(shù)組。

// 查詢student表的全部數(shù)據(jù)

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

? ? console.log(r);

})

(2)根據(jù)條件查詢find(條件)

返回的是符合條件的數(shù)組。如果沒有滿足條件的結(jié)果,就返回一個空數(shù)組。

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

? ? console.log(r);

})

(3)返回表中的第一個對象findOne()

findOne方法返回的是對象。

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

console.log(r);

})

(4)根據(jù)條件查詢 findOne(條件)

查詢第一個滿足條件的,返回的是對象,如果沒有滿足條件的結(jié)果,就返回null。

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

? ? console.log(r);

})

(5)查詢某個范圍內(nèi)的數(shù)據(jù)

① 查詢大于某數(shù)值的數(shù)據(jù) $gt

// 查詢年齡于20歲的學(xué)生信息

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

console.log(r);

})

② 查詢大于某數(shù)值的數(shù)據(jù) $lt

// 查詢年齡小于20歲的學(xué)生信息

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

console.log(r);

})

③ 查詢兩數(shù)之間的數(shù)據(jù) {$gt:num1,$lt:num2}}

// 查詢年齡在20歲到40歲之間的學(xué)生信息

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

console.log(r);

})

④ 查詢兩數(shù)之間的數(shù)據(jù)(包括兩數(shù)) {$gte:num1,$lte:num2}}

// 查詢年齡在20歲到40歲之間的學(xué)生信息(包括20和40)

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

console.log(r);

})

(6)根據(jù)正則表達(dá)式匹配查詢條件(用于模糊查詢)

$regex 正則,用于模糊查詢。

select方法,篩選查詢列。注意:_id列默認(rèn)會返回,如果不需要查詢id,就加上-_id。

// 查詢姓名中包含'劉'的學(xué)生信息,只返回name、sex、age列

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

? ? console.log(r);

})

注意:如果正則條件是模板字符串,需要使用new RegExp()創(chuàng)建。

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

(7)匹配包含

① $in 滿足其中一個元素的數(shù)據(jù)

?// 查詢愛好中包含‘睡覺’或‘學(xué)習(xí)’的學(xué)生信息

Student.find({hobbies:{$in:['睡覺','學(xué)習(xí)']}}).select('name sex age hobbies -_id').then(r=>{

? ? console.log(r);

})

② $all 滿足所有元素的數(shù)據(jù)

// 查詢愛好中包含‘睡覺’和‘學(xué)習(xí)’的學(xué)生信息

Student.find({hobbies:{$all:['睡覺','學(xué)習(xí)']}}).select('name sex age hobbies -_id').then(r=>{

console.log(r);

})

(8)對查詢結(jié)果排序sort()

① 升序排列

// 根據(jù)年齡升序查詢學(xué)生信息

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

? ? console.log(r);

})

② 降序排列

// 根據(jù)年齡降序查詢學(xué)生信息

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

? ? console.log(r);

})

③ 根據(jù)性別升序,再根據(jù)年齡降序

// 先返回相同性別的學(xué)生,相同性別的學(xué)生再根據(jù)年齡降序

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

? ? console.log(r);

})

(9)分頁查詢

skip()跳過多少條數(shù)據(jù);limit()限制查詢數(shù)量。

// 每頁2條數(shù)據(jù),顯示第2頁

let?pageIndex?=?2//定義頁碼

let?pageSize?=?2//定義每頁數(shù)量

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)刪除數(shù)據(jù)

① 刪除單個 findOneAndDelete()

刪除成功后,返回刪除的對象

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

? ? console.log(r)

})

② 刪除單個 deleteOne()

刪除成功后,返回刪除的數(shù)量

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

? ? console.log(r)

})

③ 刪除多個 deleteMany()

刪除成功后,返回刪除的數(shù)量

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

console.log(r);

})

十三、Express框架

1、定義

Express是一個基于Node平臺的web應(yīng)用開發(fā)框架,它提供了一系列的強(qiáng)大特性,幫助你創(chuàng)建各種Web應(yīng)用。

使用npm install express 命令進(jìn)行下載。

2、基本步驟

(1)導(dǎo)入express

let?express?=?require('express')

(2)通過express函數(shù),創(chuàng)建并返回一個web服務(wù)器對象

let?app?=?express()

(3)啟動服務(wù)器,并監(jiān)聽一個端口號(端口號是自定義的)

app.listen(8848,()=>{

? ? console.log('服務(wù)器成功開啟,端口號是8848');

})

3、中間件

(1)定義

中間件就是一堆方法,可以接收客戶端發(fā)來的請求、可以對請求做出響應(yīng),也可以將請求繼續(xù)交給下一個中間件繼續(xù)處理。

(2)app.use中間件用法

app.use 匹配所有的請求方式,可以直接傳入請求處理函數(shù),代表接收所有的請求。所有的請求,都會先走use,作用是攔截器。

實(shí)際開發(fā)中,我們用use中間件方法里面去判斷用戶的權(quán)限,從而確定該用戶能否繼續(xù)請求相關(guān)的接口。

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

?//表示:允許跨域請求

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

?//next方法,表示繼續(xù)往下執(zhí)行

? ? next()

})

4、跨域

(1)定義

同源策略:協(xié)議名,主機(jī)名(域名或ip地址),端口號必須完全相同。違背同源策略就是跨域。

ajax請求,必須要遵循同源策略。

(1)解決跨域

設(shè)置響應(yīng)頭,允許跨域請求。

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

(2)允許自定義請求頭信息

響應(yīng)頭*表示所有類型的頭信息都可以接受。

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

5、get請求接口

(1)get請求參數(shù)的獲取

req.query接收前端傳遞的GET請求參數(shù),框架內(nèi)部會將GET參數(shù)轉(zhuǎn)換為對象并返回。

(2)定義get請求接口

req是請求對象,里面保存的是客戶端傳過來的請求參數(shù)。

res是響應(yīng)對象,用于給客戶端響應(yīng)結(jié)果。

res.send()將結(jié)果返回給前端。

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

?res.send('hello')

})

6、post請求接口

(1)post請求參數(shù)的獲取

req.body接收前端傳遞過來的POST請求參數(shù)。

接收POST請求參數(shù),服務(wù)器需要進(jìn)行設(shè)置。

通過express.json()中間件,解析表單中的JSON格式數(shù)據(jù)。

通過express.urlencoded()中間件,解析表單中的url-encoded格式數(shù)據(jù)。

// 設(shè)置允許接收json格式的數(shù)據(jù)({"name":"張三","age":20})

app.use(express.json())

// 設(shè)置允許接收urlencoded格式的數(shù)據(jù)("name=張三&age=20")

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

(2)定義post請求接口

app.post('/add', (req,?res) =>?{

console.log(req.body);// 接收請求參數(shù)

?res.send('hello')

})

十四、AJAX

1、原生AJAX

(1)GET請求

GET請求的參數(shù),使用?直接拼接在url地址后面,如果有多個參數(shù)使用&符號。

參數(shù)例如:name=${name}&pageIndex=${pageIndex}

// 01.創(chuàng)建xhr對象

let?xhr?= new?XMLHttpRequest()

// 02.初始化請求

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

// 03.發(fā)送請求

xhr.send()

// 04.監(jiān)聽事件,并接收結(jié)果

xhr.onreadystatechange?= function(){

//請求完成

? ? ?if(xhr.readyState===4){

//請求成功

? ? ? ? ?if(xhr.status===200){? ? ?

console.log(xhr.response);//打印響應(yīng)結(jié)果

? ? ? ? ?}

? ? ?}

?}

(2)POST請求

① 設(shè)置Content-Type請求頭

POST請求時,需要設(shè)置Content-Type請求頭,告訴服務(wù)器傳遞的數(shù)據(jù)格式。

如果是urlencoded格式的數(shù)據(jù):

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

如果是json字符串格式的數(shù)據(jù):

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

② 參數(shù)傳遞

post請求的參數(shù),在發(fā)送時傳遞。

傳遞urlencoded格式的數(shù)據(jù):

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

傳遞json字符串格式的數(shù)據(jù):

let?params?= {

? ? ?name:name,

hobbies:hobbies.split(',')//愛好,轉(zhuǎn)為數(shù)組

?}

xhr.send(JSON.stringify(params))// 將對象轉(zhuǎn)為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(請求地址, {參數(shù)名: 參數(shù)值}, 回調(diào)函數(shù))

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

console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)

? })

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

$.post(請求地址, {參數(shù)名: 參數(shù)值}, 回調(diào)函數(shù))

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

console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)

? })

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

① get請求

? ? ? ? ? ? $.ajax({

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

url:?url,// 請求方式get 或 post

dataType:?"json",?// 返回的數(shù)據(jù)類型

?// 請求成功后的回調(diào)函數(shù)

success:?function?(r) {

console.log(r)

? ? ? ? ? ? ? ? },

?// 請求失敗后調(diào)用的函數(shù)

error:?function?(err) {

? ? ? ? ? ? ? ? ? ? console.log('請求錯誤')

? ? ? ? ? ? ? ? }

? ? ? ? ? ? });

② post請求

發(fā)送post請求時,如果請求參數(shù)是json字符串格式,需要設(shè)置contentType請求頭為'application/json'。contentType默認(rèn)值 "application/x-www-form-urlencoded"。

let?params?= {

? ? ?????name:name,

? ? ?????hobbies:hobbies.split(',')

???}

$.ajax({

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

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

data:JSON.stringify(params),// 請求的參數(shù)

? ? ? ? ?contentType:'application/json',

success:function(r){

console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)

? ? ? ? ?}

? ? })

3、axios AJAX

(1)引入axios庫

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

(2)GET請求

① get請求的參數(shù)可以直接用?拼接在URL中。

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

console.log(response);

}).catch(function?(error) {

console.log(error);

? ? ? ? });

② get請求的參數(shù)可以寫在params對象中。

注意:get請求的返回結(jié)果包含很多信息,需要將結(jié)果中的data解構(gòu)出來。data中存放的才是需要的數(shù)據(jù)。

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

? ? ? ? ? ? params:?{

? ? ? ? ? ? ???name:name

? ? ? ? ? ?}

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

? ? ? ? ? ?console.log(data)

? ? ? })

(3)POST請求

post請求參數(shù)直接寫在對象中傳入。

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:?{//請求參數(shù)

? ? ? ? ? ? ? ? ? ? vip:?10,

? ? ? ? ? ? ? ? ? ? level:?30

? ? ? ? ? ? ? ? }, ? ? ? ? ?

headers:?{//設(shè)置請求頭信息

? ? ? ? ? ? ? ? ? ? a:?100,

? ? ? ? ? ? ? ? ? ? b:?200

? ? ? ? ? ? ? ? },

?//請求體參數(shù)

? ? ? ? ? ? ? ? data:?{

? ? ? ? ? ? ? ? ? ? username:?'admin',

? ? ? ? ? ? ? ? ? ? password:?'admin'

? ? ? ? ? ? ? ? }

}).then(response=>?{

console.log(response);

?//響應(yīng)狀態(tài)碼

console.log(response.status);

?//響應(yīng)狀態(tài)字符串

console.log(response.statusText);

?//響應(yīng)頭信息

console.log(response.headers);

?//響應(yīng)體

console.log(response.data);

? ? ? ? ? ? })

4、fetchAJAX

1)fetch定義

fetch是一個瀏覽器內(nèi)置的全新的請求API。之前我們使用的jquery和axios的請求方法只是對XMLHttpRequest對象的封裝。

fetch()函數(shù)的第一個參數(shù)是url地址,第二個參數(shù)是配置對象。

(2)GET請求

GET請求的參數(shù),使用?直接拼接在url地址后面,如果有多個參數(shù)使用&符號。

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

method:'GET',//設(shè)置請求方式(默認(rèn)是GET)

}).then(response=>{

?// 第一個then,用于返回請求的狀態(tài)信息(檢查請求是否成功等等)

?// 再通過請求狀態(tài)對象的.json()方法,返回請求結(jié)果

returnresponse.json()

}).then(r?=>{

console.log(r)// 返回請求結(jié)果

?})

(3)POST請求

發(fā)送post請求時,請求參數(shù)如果是json字符串格式,需要配置請求頭headers,設(shè)置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請求參數(shù)

}).then(r=>{

returnr.json()

}).then(r=>{

console.log(r)// 返回請求結(jié)果

? ? ? ? ? ? })

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、文件/文件夾管理 ls 列出當(dāng)前目錄文件(不包括隱含文件)ls -a 列出當(dāng)前目錄文件(包括隱含文件)ls -...
    BerL1n閱讀 7,895評論 0 78
  • 完全沒想到這篇文章的閱讀量有點(diǎn)多,之前沒有考慮什么就直接發(fā)布了,對此表示歉意,所以重新找了一篇文章匯總,以免在坑到...
    BabyFatXu閱讀 1,814評論 0 1
  • 一、linux簡介 linux 系統(tǒng)可以用 Windows 系統(tǒng)來做一個類比,操作系統(tǒng)都是由一堆文件構(gòu)成的。在wi...
    jinghenggl閱讀 587評論 0 0
  • Windows系統(tǒng) WIN+R打開運(yùn)行輸入cmd即可進(jìn)入命令行,也可以通過cmd /c 命令 和 cmd /k 命...
    云間一壺酒閱讀 309評論 0 0
  • 一. 命令基本格式 1. 含義: [seal@localhost ~]$ 其中seal為用戶名稱(即用戶名),ro...
    AE86過彎不剎車閱讀 343評論 0 0

友情鏈接更多精彩內(nèi)容