一:簡(jiǎn)單的Node.js介紹
簡(jiǎn)單的說Node.js是運(yùn)行在服務(wù)端的javascript
Node.js 是基于Chrome V8引擎的javascipt運(yùn)行環(huán)境
Node.js 使用了一個(gè)事件驅(qū)動(dòng)昔头、非阻塞式I/O模型,使其輕量高效
Node.js 的包管理器npm撵颊,是全球最大的開源庫(kù)生態(tài)系統(tǒng)。node中的所有的模塊都可以 在npm中找到并下載使用
二:Node雜七雜八的東西
(1)安裝:直接打開安裝包安裝就行,一般安在c盤针贬;安完以后吧棘劣,在Dos窗口上輸入node -v來檢查你的版本號(hào) 還有npm -v
(2)讓程序在node環(huán)境中運(yùn)行起來
如果用的不是webstorm這個(gè)編輯器的話,其他的話:
打開控制臺(tái)
cd 把文件托拉進(jìn)來
node 要執(zhí)行的文件名
三:編寫一段http服務(wù)器代碼
先引入http模塊(node的相關(guān)功能都是由模塊提供的至扰,所以要使用http服務(wù)鳍徽,就要引入http模塊)
// 引入http模塊
(1) var http = require('http');
//創(chuàng)建http服務(wù)
(2) var server = http.createServer(function(req,res){
//在創(chuàng)建http服務(wù)時(shí),傳入了一個(gè)回調(diào)函數(shù)作為參數(shù)敢课,在收到客戶端請(qǐng)求時(shí)(就是在用戶通過瀏覽器地址欄發(fā)送請(qǐng)求時(shí))會(huì)觸發(fā)這個(gè)回調(diào)函數(shù)
這個(gè)回調(diào)函數(shù)里的倆參數(shù)
req:請(qǐng)求對(duì)象:可以從這個(gè)參數(shù)里獲取到 請(qǐng)求路徑req.url 請(qǐng)求方法req.method 等
res:響應(yīng)對(duì)象:可以通過這個(gè)參數(shù)向客戶端發(fā)送信息( res.write()/res.send()一般是在控制臺(tái)上打印出來的東西);
發(fā)送頁(yè)面(res.sendFile()一般在用這個(gè)方法的時(shí)候要引入fs模塊阶祭,fs模塊會(huì)在下面進(jìn)行解釋)
})
//配置路由
就是根據(jù)用戶在瀏覽器地址欄上輸入的網(wǎng)址請(qǐng)求的不同路徑,向前端發(fā)送不同的數(shù)據(jù)呀直秆,頁(yè)面呀啥的(下面是一個(gè)簡(jiǎn)單的沒有參數(shù)的get請(qǐng)求服務(wù))
(3)var server = http.createServer(function(req,res){
if (req.url=='/index.html'||req.url=='/'){
res.write('開新');
res.end();
//這是向客戶端發(fā)送一些數(shù)據(jù)濒募,并不是網(wǎng)頁(yè),當(dāng)然會(huì)在頁(yè)面上顯示出來嘛
var path=fs.realpathSync('index.html');
res.sendFile(path);
//使用文件的讀寫操作把存在服務(wù)器中的文件寫進(jìn)res里
var rs=fs.createReadStream('./login.html');
rs.pipe(res);
//上邊這兩種都是用來向客戶發(fā)送回來網(wǎng)頁(yè)的
}
如果用戶請(qǐng)求的文件在服務(wù)器中不存在圾结,就利用狀態(tài)嗎返回對(duì)應(yīng)的編碼
res.statusCode = 404;
res.end('not found)
})
//監(jiān)聽服務(wù)器端口號(hào)
server.listen(8888,function () {
console.log('服務(wù)器啟動(dòng)完畢');
})
咱們?cè)谶@再說個(gè)url模塊
url模塊下的parse方法可以把請(qǐng)求的url由字符串轉(zhuǎn)為對(duì)象
完整的代碼
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(req,res){
//路徑轉(zhuǎn)換
var urlObj = url.parse(req.url,true);
console.log(urlObj.path);//獲取請(qǐng)求的路徑
console.log(urlObj.query)//獲取get
提交的參數(shù)
if (urlObj.pathname=='/index'||urlObj.pathname=='/'){
var rs=fs.createReadStream('./index.html');
rs.pipe(res);
}else if(urlObj.pathname=='./login'){
//驗(yàn)證用戶名和密碼
if(urlObj.query.user=='123'&&urlObj.query.pass=='234')
var rs=fs.createReadStream('./success.html');
rs.pipe(res);
}else{
var rs=fs.createReadStream('./error.html');
rs.pipe(res);
}else{
res.statusCode = 404;
res.end('404')
}
})
server.listen(8888,function () {
console.log('服務(wù)器啟動(dòng)完畢');
})
當(dāng)引入外部文件時(shí)萨咳,比如css啥的
//判斷:請(qǐng)求的頁(yè)面是否存在
var bol = fs.existsSync('.'+urlObj.pathname);
//路由
if (bol){
var rs=fs.createReadStream('.'+urlObj.pathname);
rs.pipe(res);
}else{
res.statusCode = 404;
res.end('404')
}
四 :fs模塊
fs模塊又叫文件模塊;此模塊提供了 對(duì)本地磁盤中的文件讀寫疫稿、創(chuàng)建培他、刪除、以及文件目錄操作的相關(guān)方法
首先我們要先把模塊引進(jìn)來
var fs = require('fs');
(1)文件讀纫抛:(異步讀纫荨)
fs.readFile('data.txt',function (err,data) {//從磁盤里讀文件
//err在讀取失敗時(shí)有值,有值是錯(cuò)誤信息途蒋,如果沒錯(cuò)則err為null猛遍,data參數(shù)中保存的就是讀取出來的數(shù)據(jù)
if (err){
console.log(err);
}else{
console.log(data);
}
})
(同步讀取)
var str = fs.readFileSync('./smile.txt','utf-8')
console.log(str);
(2)寫入文件
(異步寫入)
fs.writeFile('hello.txt','hello world',{
文件寫入操作:writeFile(a,b,c,d)a:要寫入的路 徑号坡,如果路徑不存在就創(chuàng)建這個(gè)路徑懊烤;b:要寫入的數(shù)據(jù),c:寫入的操作宽堆;d:寫入結(jié)束的回調(diào)函數(shù)
flag:'w'//a,表示拼接寫入腌紧,如果文件中已經(jīng)有數(shù)據(jù)則在元數(shù)據(jù)的末尾拼接新數(shù)據(jù);w:是覆蓋式的寫入畜隶,如果文件中已經(jīng)有數(shù)據(jù)壁肋,就會(huì)覆蓋原來的數(shù)據(jù)
},function (err,data) {
console.log(err);
console.log(data);
})
(同步寫入)
var str = 'sdssdsds';
fs.writeFileSync('./smile.txt',str,{flag:'a'})
(3)復(fù)制文件
文件的復(fù)制操作号胚,當(dāng)數(shù)據(jù)成功讀取后載寫入另一個(gè)文件中
fs.readFile('data.txt',function (err,data) {
if (err){
console.log(err);
}else{
fs.writeFile('data副本.txt',data,{
flag:'w'
},function (err) {
if (err){
console.log(err);
}else{
console.log('復(fù)制成功');
}
})
}
})
fs模塊還有創(chuàng)建新目錄啥的功能,先不寫浸遗,因?yàn)闉橥嗣ㄐ玻任蚁朊靼琢嗽賹懓?br>
五:文件的管道流操作
使用管道流操作與普通讀寫操作的區(qū)別:管道流操作使用流式讀取,寫入文件每讀取64k時(shí)就執(zhí)行一次寫入操作
而普通讀寫操作需要先把文件全部讀取進(jìn)內(nèi)存以后才進(jìn)行寫入跛锌,這樣容易造成內(nèi)存溢出
//管道流讀寫
var fs=require('fs');
//吧文件分割成若干塊弃秆,每一塊大小是64k,逐塊操作這個(gè)文件髓帽,來達(dá)到節(jié)約內(nèi)存的目的
var rs=fs.createReadStream('data.txt');//創(chuàng)建讀入流
var ws=fs.createWriteStream('hello.txt');//創(chuàng)建寫入流
讀取流載每讀出64k的數(shù)據(jù)后菠赚,會(huì)觸發(fā)一次data事件,通過該事件函樹拿到讀取出來的數(shù)據(jù)
rs.on('data',function (chunk) {//事件函數(shù)的參數(shù)chunk保存的就是讀取流每次讀取出來的數(shù)據(jù)氢卡,如果沒有指定讀取編碼锈至,則默認(rèn)一buffer格式讀取
// console.log(chunk.toString());
// ws.write(chunk,function () {//通過寫入流的write方法把要寫入的數(shù)據(jù)通過寫入流寫入
// console.log('寫入結(jié)束');
// })
})
也可以直接:
rs.pipe(ws);//rs讀取流下的pipe方法參數(shù)是寫入流對(duì)象,該方法可以把讀取流當(dāng)前讀出的64k數(shù)據(jù)傳給寫入流译秦,當(dāng)寫如流寫入完成再進(jìn)行后續(xù)的讀取操作
pipe操作為同步操作峡捡,只有當(dāng)讀取出來的數(shù)據(jù)寫入完成后才進(jìn)行下一次的讀取操作,保證內(nèi)存中沒有積壓數(shù)據(jù)筑悴,但是會(huì)延長(zhǎng)讀寫時(shí)間
data時(shí)間在讀的同時(shí)寫入们拙,讀寫互不干擾。但是由于磁盤讀寫速度不一致會(huì)有積壓數(shù)據(jù)的現(xiàn)象阁吝,但是能縮短讀寫時(shí)間
未完待續(xù)..........