您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“nodejs有什么作用”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“nodejs有什么作用”這篇文章吧。
一、概覽
1、html可以在瀏覽器直接打開運行,是因為瀏覽器是html文件的解析器
而js文件不能在瀏覽器直接運行,是因為瀏覽器不支持解析js文件,需要有一個解析器來解析js文件
可以下載安裝nodejs解析器,并且里面自帶了npm,通過node.exe可以直接運行js文件,是通過命令行的形式運行的
要運行某個js文件,直接node + 要運行的js文件名稱或者直接是js代碼,按回車即可
js操作的是瀏覽器,node操作的是電腦系統、文件等等
2、編輯器也可以直接運行,推薦使用webstorm
3、在Ecmascript部分,node和js其實是一樣的,比如數據類型的定義、語法結構、內置對象
在js中的頂層對象:window
在node中的頂層對象:global,沒有window這個概念
二、模塊
es6通過import export來進行模塊化
nodejs通過require來進行模塊化
html通過script標簽來引入js文件
1、在nodeJs里面,一個js文件就是一個模塊,每個模塊都有自己的作用域,
我們使用var聲明的變量,不是全局的,而是屬于當前模塊下的
比如:1.js
var a = 100;
console.log(a); //100
console.log(global.a); //undefined ,不是全局下面的變量
global.a = 200;
console.log(a); //100 仍然是開始定義的100
console.log(global.a); //這時候才是200
2、filename:表示當前文件的絕對路徑
dirname:表示當前文件所在目錄的絕對路徑
它們并非全局的,而是模塊作用域下的
所以global.filename是訪問不到的,返回undefined
console.log(filename); //E:\webstorm文件夾\index.js
console.log(__dirname); //E:\webstorm文件夾
3、模塊路徑
require(); //可以是絕對路徑、相對路徑
不能直接是require("1.js")這種不帶./的,這種加載方式,會加載node中的核心模塊,或者是node_modules里面的慕課
4、查找文件:
首先按照加載的模塊的文件名進行查找;
如果沒有找到,則會在模塊文件名稱后面自動加上.js的后綴,然后進行查找;
如果還沒有找到,則會在模塊文件名稱后面自動加上.json的后綴,然后進行查找;
如果還沒有找到,則會在模塊文件名稱后面自動加上.node的后綴,然后進行查找;
如果還沒有找到,就會報錯。
5、
在一個模塊中,通過var定義的變量,其作用域范圍是當前模塊,外部不能夠直接訪問到;
如果我們想一個模塊能夠訪問另一個模塊中定義的變量,可以通過:
把變量作為global對象的一個屬性(不推薦)
global.a = 100;
使用模塊對象 module,這個對象不是全局的,而是每個模塊下的對象
模塊對象 module用于:保存提供和當前模塊有關的一些信息,下面有很多屬性:
exports:{}; //module的子對象,通過這個對象可以把一個模塊中的局部變量暴露出去,供外部訪問
因為exports也是一個對象,所以暴露變量出去之前,先聲明一個key值,value值就是這個局部變量
var a = 100; module.exports.name = a; require(); //返回值就是module.exports對象
6、在模塊作用域下,還有一個內置的模塊對象,exports,它其實就是module.exports
所以:
module.exports.name = a; 可以寫成 exports.name = a;
【注意】:不要這樣操作
module.exports = [1,2,3]
也不要:exports = [1,2,3],只是追加屬性,不要修改
三、global對象 全局對象
局部:
filename
dirname
全局:
日期對象 var d = new Date()
數組 var arr = new Array(1,2,3)
定時器
三-1、process對象(進程對象)——全局對象
process === global.process //true
可以在任何地方都能訪問到,通過這個對象提供的屬性和方法,使我們可以對當前運行的程序的進程進行訪問和控制
1、process.argv
console.log(process.argv); // [ 'D:\Program Files\nodejs\node.exe', 'E:\webstorm文件夾\2.js' ]
第一個是解析器,第二個是js文件
如果帶上參數,那么返回的數組里面就會包含你運行時帶入的參數
舉例: node process.argv a=1 // [ 'D:\Program Files\nodejs\node.exe', 'E:\webstorm文件夾\2.js','a=1' ]
2、process.execPath
開啟當前進程的這個可執行文件的絕對路徑
3、env
返回用戶環境信息
4、version
返回node版本信息
5、versions
返回node以及node依賴包版本信息
6、pid
返回當前進程的pid 進程是node.exe
7、title
返回當前進程的顯示名稱(Getters/Setters)
8、arch
返回當前CPU處理器架構 arm/ia32/x64
9、platform
返回當前操作平臺
10、cwd()
返回當前進程的工作目錄
11、chdir(directory)
改變當前進程的工作目錄
12、memoryUsage()
返回node進程的內存使用情況,單位是byte
12、exit(code)
退出
13、kill(pid)
向進程發送信息
14、IO
a、stdin、stdout:標準輸入輸出流(IO)
標準輸入設備:向計算機輸入數據和信息的設備,是計算機與用戶或其他設備通信的橋梁。
例如:鼠標、鍵盤、攝像頭等等
標準輸出設備:是計算機硬件系統的終端設備,把計算機數據或信息以數字、字符、圖像、聲音等形式表現出來。例如:顯示器、打印等等
stdin、stdout提供了操作輸入數據和輸出數據的方法,我們也通常稱為IO操作
stdin:標準輸入流
stdout:標準輸出流
console.log(...) === process.stdout.write(...);
b、默認情況下,輸入流是關閉的,要監聽處理輸入流數據,首先要開啟輸入流
//開啟 process.stdin.resume(); 監聽用戶的輸入數據,輸入完成按下回車 process.stdin.on('data',function(chunk){ console.log('用戶輸入了:'+chunk); })
會一直監聽,用戶輸入完成按下回車顯示數據,再按下仍然會顯示第二次輸入的數據
四、Buffer類:類似數組
1、定義:一個用于更好的操作二進制數據的類
我們在操作文件或者網絡數據的時候,其實操作的就是二進制數據流;Node為我們提供了一個更加方便的去操作這種數據流的類Buffer,他是一個全局的類,global.Buffer === buffer
JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。
但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。
在 Node.js 中,Buffer 類是隨 Node 內核一起發布的核心庫。Buffer 庫為 Node.js 帶來了一種存儲原始數據的方法,可以讓 Node.js 處理二進制數據,每當需要在 Node.js 中處理I/O操作中移動的數據時,就有可能使用 Buffer 庫。原始數據存儲在 Buffer 類的實例中。一個 Buffer 類似于一個整數數組,但它對應于 V8 堆內存之外的一塊原始內存。
Buffer.alloc(size); 創建一個Buffer對象,并且為這個對象分配一個空間大小,大小是size的8位字節;當我們為一個buffer對象分配了一個空間大小以后,其長度是固定的,不能更改。也就是后續不能再增加內容了
<Buffer 72 75 6e 6f 6f 62> //控制臺顯示的是16進制的
Buffer.from(array): 返回一個被 array 的值初始化的新的 Buffer 實例(傳入的 array 的元素只能是數字,不然就會自動被 0 覆蓋),聲明并賦值
Buffer.from(string[, encoding]): 返回一個被 string 的值初始化的新的 Buffer 實例,encoding默認是utf8
let bf2 = Buffer.from('miaov'); //bf2.length 5 返回的是字節數,不是字符串長度
let bf3 = Buffer.from('妙味'); //bf3.length 6 一個漢字占據3個字節
2、Buffer類方法
bf.length; //buffer的字節長度
bf[ index ]; //獲取或者設置在index索引位置的8位字節內容
bf.write(string , [offset] , [length] , [encoding]); //根據參數offset偏移量和指定的encoding編碼方式,將參數string寫入數據寫入buffer
bf.toString( [encoding],[start],[end] ); //根據encoding返回一個解碼的string類型
bf.toJSON(); //返回一個JSON表示的Buffer實例,JSON.stringify將會默認調用來字符串序列化這個Buffer實例
bf.slice( [start],[end] ); //返回一個新的buffer,這個buffer將會和老的buffer引用相同的內存地址;
注意:修改這個新的buffer實例slice切片,也會改變原來的buffer
bf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
let bf2 = Buffer.from('miaov'); console.log(bf2); //<Buffer 6d 69 61 6f 76> //十六進制 console.log(bf2.toString()); //'miaov' for (let i=0;i<bf2.length;i++){ //m的十六進制是6d;十進制是109;二進制是0110 1101 console.log(bf2[i]); //109 105 97 111 118 十進制 console.log(String.fromCharCode(bf2[i])) // m i a o v 圖形字符 } let bf = Buffer.alloc(5); let str = 'miaov'; //bf.write(str); //console.log(bf); //<Buffer 6d 69 61 6f 76> // bf.write(str,1); // console.log(bf); //從buffer第1位開始寫入,第0位用00補上,<Buffer 00 6d 69 61 6f> bf.write(str,1,3); console.log(bf); //只寫入三位,其他位用00補上,<Buffer 00 6d 69 61 00> console.log(bf.toJSON()); //{ type: 'Buffer', data: [ 0, 109, 105, 97, 0 ] }
3、Buffer中的靜態方法(又叫類方法,即不需要實例化即可使用的方法)
Buffer.isEncoding(encoding):如果給定的編碼encoding是有效的,返回true;否則返回false
Buffer.isBuffer(obj); 測試這個obj是否是一個Buffer
Buffer.byteLength(string,[encoding]):將會返回這個字符串的真實byte字節長度。encoding默認編碼是utf8
let str1 = 'json'; console.log(str1.length); //4 字符長度 console.log(Buffer.byteLength(str1)); //4 字節長度
Buffer.concat(list,[totalLength]):返回一個保存著將傳入Buffer數組中所有buffer對象拼接在一起的buffer對象
list是buffer對象,返回值是多個buffer對象拼接成的一個buffer對象
totalLength是拼接后的字節長度,不傳是計算后的所有的字節長度,(建議預先設置,節省計算時間)
五、文件系統模塊 File System
1、該模塊是核心模塊,需要使用require導入后使用:let fs = require('fs');
2、該模塊提供了操作文件的一些API
異步的打開一個文件:
fs.open(path,flags,[mode],callback)
path:要打開文件的路徑;
flags:打開文件的方式:讀/寫
mode:設置文件的模式:讀/寫/執行
callback:回調函數,接受2個參數:err、fd
err:文件打開失敗的錯誤保存在err里面,如果成功err為null
fd:被打開文件的標識,和定時器類似,用于后續要操作文件的標識,即后續如果要操作某個打開的文件,把這個文件標識傳到后續操作的某些方法里面去,即可知道操作的是當前文件
fs.open()的同步版:
fs.openSync(path,flags,[mode])
從指定的文檔標識符fd讀取文件數據
fs.read(fd,buffer,offset,length,position)
fd:通過open方法成功打開一個文件返回的編號
buffer:buffer對象,用于存儲打開文件內部的信息
offset:偏移量,數據從buffer對象里面的第幾位開始存儲,起始是0
length: 讀取的內容長度
position:從文件的第幾位開始讀取,默認是0,即從頭開始
callback:接受三個參數,err錯誤信息、length返回的新的buffer對象的長度;newBf:返回的新的buffer對象
fs.read的同步版本,返回bytesRead的個數
fs.readSync(fd,buffer,offset,length,position,callback)
*通過文件標識fd,向指定的文件中寫入buffer
fs.write(fd,buffer,offset,length,[position],callback)
同步版本:fs.writeSync(fd,buffer,offset,length,[position])
fd:通過open方法成功打開一個文件返回的編號
buffer:要寫入到文件的數據
offset:從buffer對象中第幾位開始寫入數據,默認是0
length: 要寫入的buffer數據的長度
position:向指定的文件的第幾位開始寫入buffer數據,默認是0,即從頭開始寫入數據,如果開頭已經有數據,那么新的數據會覆蓋原始數據
callback:接受三個參數,err錯誤信息、length寫入數據的buffer對象的長度;newBf:寫入數據的buffer對象
*通過文件標識fd,把data寫入到文檔中,如果data不是buffer對象的實例,則會把值強制轉換成為一個字符串
fs.write(fd,data,[position],[encoding],callback)
同步版本:fs.writeSync(fd,data,[position],[encoding])
data:直接是一個字符串,此時不再從第幾位寫入了,而是全部寫入到文件里,所以沒有offset參數
關閉一個打開的文件
fs.close(fd,callback)
同步版本:fs.closeSync(fd)
六、更好用的文件系統方法
1、fs.writeFile(filename,data,[options],callback)
異步的將數據寫入一個文件,如果文件不存在就新建,如果文件原先存在,則會被替換;data可以是一個string,也可以是一個原生buffer
同步版本:fs.writeFileSync(filename,data,[options])
2、fs.appendFile(filename,data,[options],callback)
異步的將數據添加到一個文件的尾部,如果文件不存在就新建,如果文件原先存在,則會將數據追加到文件的尾部;data可以是一個string,也可以是一個原生buffer
同步版本:fs.appendFileSync(filename,data,[options])
3、fs.readFile(filename,[options],callabck)
異步讀取一個文件的全部內容
同步版本:fs.readFileSync(filename,[options])
4、fs.exists(path,callback)
檢查指定路徑的文件或者目錄是否存在
同步版本:fs.existsSync(path)
5、fs.unlink(path,callback)
刪除一個文件
同步版本:fs.unlink(path)
let fs = require('fs'); let filename = '2.txt'; //異步 if(fs.exists(filename,(err)=>{ if(!err){ fs.writeFile(filename,'hello',(err)=>{ if(err){ console.log("文件創建失敗") }else{ console.log("文件創建成功") } }) }else{ fs.appendFile(filename,'-world',(err)=>{ if(err){ console.log('文件追加失敗') }else{ console.log('文件追加成功') } }) } })); //同步 if(!fs.existsSync(filename)){ console.log('文件創建成功'); fs.writeFileSync(filename,'hello') }else{ console.log('文件追加成功'); fs.appendFileSync(filename,'-world') }
6、fs.rename(oldPath,newPath,callback)
重命名
同步版本:fs.renameSync(oldPath,newPath)
7、fs.stat(path,callback)
讀取文件信息的狀態,不是文件內部的內容,返回值是一個json,包括文件類型、文件日期、文件大小等等
mode=33206表示該文件是文件類型,mode=16822表示該文件是文件夾
同步版本:fs.statSync(path)
8、fs.watch(filename,[options],[listener])
觀察指定路徑的改變,filename可以是文件或者目錄
//listener是一個監聽器,回調函數,有2個參數:事件event和被監聽文件的名稱filename
9、fs.mkdir(path,[mode],callback) //mode模式,是只讀還是讀寫模式
創建文件夾
同步版本:fs.mkdirSync(path,[mode])
10、fs.readdir(path,callback)
讀取文件夾
同步版本:fs.readdirSync(path)
回調函數包括2個參數,err錯誤信息和當前文件夾下面所有的文件和文件夾信息fileList
11、fs.rmdir(path,callback)
刪除文件夾
同步版本:fs.rmdirSync(path)
七、使用node進行web開發
1、用戶上網流程
用戶輸入https://www.baidu.com/
通過瀏覽器發送https請求(類似于打電話撥號),請求baidu.com,這個域名可以轉換為ip地址
通過ip定位,到網絡中指定的一臺機器上,然后該機器會接收到該用戶發送過來的請求,然后對該請求進行處理,返回對應的內容
簡言之:
用戶通過瀏覽器發送一個http請求到指定的服務器
服務器接收到該請求,對該請求進行分析和處理
服務器處理完成之后,返回對應的數據到用戶機器
瀏覽器接受到服務器返回的數據,并根據接收到的數據進行分析和處理
web開發:就是兩臺機器之間的數據交互,客戶端與服務端的交互
由客戶端發送一個http請求到指定的服務端 ——> 服務端接收并處理請求 ——> 返回數據到客戶端,類比迅雷下載
http協議:
要進行web開發,首先就必須處理關于服務端接收請求的這一過程,所以要搭建服務器,該服務器可以接收來自任何客戶端的鏈接和請求,然后進行對應處理
2、http模塊
let http = require('http');
使用該模塊可以進行服務器的搭建
server.listen(); //如果不傳參數,默認系統會自動分配端口號,但是不建議,要主動設置端口號及主機名
res.writeHead( 200,'',{ //200,默認返回ok
content-type : 'text/html;charset=utf-8' //會將返回信息當成html輸出到頁面,html標簽起作用
content-type : 'text/plain' //會將返回信息當成文本文件輸出到頁面,html標簽不起作用
} )
/* * 搭建一個http的服務器,用于處理用戶發送的http請求 * 需要使用node提供一個模塊 http * */ //加載一個http模塊 let http = require('http'); //通過http模塊下的createServer創建并返回一個web服務器對象 let server = http.createServer(); server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('linstening...') }) server.on('request',(req,res)=>{ //req是客戶端發送的數據,res是服務端返回的數據 console.log('有客戶端請求了') //console.log(req); //req里面有請求頭、域名后面附帶的路徑信息/a/index.html、method方式 //console.log(res); //res里面包括response正文信息(即網頁上顯示的內容)以及正文之外的一些信息,比如返回頭信息(網頁上不可見) res.writeHead('200','',{ 'content-type':'text/html;charset=utf-8' }) // res.write('<h2>hello</h2>'); // res.end(); //可以合并為一步 res.end('<h2>hello</h2>'); }) server.listen(8080,'localhost');
3、url模塊
let url = require('url');
url.parse(); //專門用于解析url路徑,返回json格式數據
4、使用querystring模塊方法對get和post提交的數據進行處理
let qs = require('querystring');
get方式發送數據
qs.parse('foo=bar&abc=xyz&abc=123'); //{foo: 'bar',abc: ['xyz', '123']}
post方式發送數據
let http = require('http'); let url = require('url'); let fs = require('fs'); let qs = require('querystring'); let server = http.createServer(); let filename = __dirname + '/html/'; server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('listening') }) server.on('request',(req,res)=>{ var urlStr = url.parse( req.url ); //返回一個對象,里面的pathname屬性和req.url一樣 switch (urlStr.pathname) { case '/': getData(filename+'index.html',req,res); break; case '/user': getData(filename+'user.html',req,res); break; case '/login': getData(filename+'login.html',req,res); break; case '/login/check': /*console.log(req.method); //get console.log(urlStr.query); //username=xiaoxiao&password=1 console.log(qs.parse(urlStr.query)); //[Object: null prototype] { username: 'xiaoxiao', password: '1' }*/ if(req.method.toUpperCase() === 'POST'){ let str = ''; req.on('data',(chunk)=>{ str += chunk; }) req.on('end',()=>{ console.log(str); //username=13795232495&password=111 console.log(qs.parse(str)); //[Object: null prototype] { username: '13795232495', password: '111' } }) } break; default: break; } }) function getData(filename,req,res) { fs.readFile(filename,(err,data)=>{ //console.log(data.toString()); //輸出頁面內的全部標簽內容 if(err){ res.writeHead(404,'',{ 'content-type':'text/html;charset=utf8' }) res.end('<h2>404</h2>') }else{ res.writeHead(200,'',{ 'content-type':'text/html;charset=utf8' }) res.end(data) } }) } server.listen(8082,'localhost');
/* * 搭建一個http的服務器,用于處理用戶發送的http請求 * 需要使用node提供一個模塊 http * */ //加載一個http模塊 let http = require('http'); let url = require('url'); //通過http模塊下的createServer創建并返回一個web服務器對象 let server = http.createServer(); server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('linstening...') }) server.on('request',(req,res)=>{ //req是客戶端發送的數據,res是服務端返回的數據 console.log('有客戶端請求了') console.log(req.url); //req里面有請求頭、域名后面附帶的路徑信息/a/index.html、method方式 //console.log(res); //res里面包括response正文信息(即網頁上顯示的內容)以及正文之外的一些信息,比如返回頭信息(網頁上不可見) switch (req.url) { case '/': res.writeHead(200,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>這是首頁</h2>'); break; case '/user': res.writeHead(200,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>這是用戶頁</h2>'); break; default: res.writeHead(404,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>404</h2>'); break; } // res.write('<h2>hello</h2>'); // res.end(); //可以合并為一步 //res.end('<h2>hello</h2>') }) server.listen(8080,'localhost');
【注意】:
1、所謂異步,就是執行成功了之后會執行一個回調函數,下面的代碼會繼續執行,即使報錯了也不妨礙下面代碼的執行;同步,就是成功了就繼續執行下面的代碼,報錯了就卡在這兒了,下面的代碼也就執行不了了。
2、所謂的參數filename,包括文件的名稱和路徑(如果有路徑的話),比如在task文件夾下創建index.html
那么filename='task/index.html'
要包括文件的名稱,不能僅僅是一個空路徑,'task/'
以上是“nodejs有什么作用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。