前提是已經(jīng)安裝好了nodejs,gitbash等工具,未裝的自行前往官方下載安裝
step1
獲取http模塊艰匙,創(chuàng)建服務(wù)器,監(jiān)聽8080端口
var http = require('http')
var server = http.createServer(function(request, response){
response.end()
})
server.listen(8080)
- 創(chuàng)建了服務(wù)器抹恳,并設(shè)置了監(jiān)聽端口后员凝,當有請求到來后,會執(zhí)行參數(shù)中的請求處理函數(shù)
- request為http請求的對象奋献,response為http應(yīng)答的對象
- response.end([data], [encoding])表示結(jié)束響應(yīng)健霹,告訴客戶端所有消息已經(jīng)發(fā)送旺上。當所有要返回的內(nèi)容發(fā)送完畢時,該函數(shù)必須被調(diào)用一次糖埋。如何不調(diào)用該函數(shù)宣吱,客戶端將永遠處于等待狀態(tài)。 參數(shù)[data]表示end()執(zhí)行完畢后要輸出的字符瞳别,如果指定了 data 的值征候,那就意味著在執(zhí)行完 response.end() 之后,會接著執(zhí)行一條 response.write(data , encoding)祟敛;參數(shù)[encoding]表示對應(yīng)data的字符編碼
step2
上一步相當于已經(jīng)創(chuàng)建了個服務(wù)器疤坝,但是請求處理函數(shù)未做任何處理,什么請求也處理不了馆铁,因此跑揉,需要添加一些簡單的處理
var http = require('http')
var server = http.createServer(function(request, response){
response.setHeader('Content-Type','text/html;charset=utf-8')
//response.write('<head><meta charset="gbk" /></head>')
response.write('<h1>你好</h1>')
response.end()
})
server.listen(8080)
這樣打開http://localhost:8080/就能看見你好兩個字啦。整個過程相當于客戶用瀏覽器訪問了http://localhost:8080/埠巨,服務(wù)器接受到了請求历谍,執(zhí)行請求處理函數(shù)。對response中放入了一些數(shù)據(jù)并且返回給瀏覽器辣垒。
上述有幾個注意點:
- Content-Type表示返回的內(nèi)容的類型望侈,此處text/html,表示返回的內(nèi)容是HTML格式勋桶,因此甜无,瀏覽器中看見的是你好;如果設(shè)置成text/plain哥遮,則在瀏覽器中看見的是 <h1>你好</h1>
- setHeader中charset=utf-8設(shè)置了返回的內(nèi)容的解碼方式岂丘。如果設(shè)置成charset=gbk,則你好兩個字會變成亂碼眠饮。此處設(shè)置的解碼的優(yōu)先級會比html等中設(shè)置的優(yōu)先級高奥帘。所以上述代碼即使注釋部分打開,也不會出現(xiàn)亂碼
step3
step2已經(jīng)能實現(xiàn)服務(wù)器返回數(shù)據(jù)啦R钦佟U!!但是你是不是有這樣的疑惑扔茅,我要展示一個寫好的html怎么辦呢已旧?總不能這樣一條一條response.write的寫吧≌倌龋可以利用到nodejs的讀寫模塊(fs)运褪,讀取相應(yīng)的html,css,js等文件返回秸讹。同時加入了path和url模塊檀咙。
首先需要找到html,css璃诀,js等文件的絕對路徑!!!
文件目錄結(jié)構(gòu)如下圖所示:
var http = require('http')
var fs = require('fs')
var url = require('url')
var path = require('path')
var server = http.createServer(function(request, response){
//獲取輸入的url解析后的對象
var pathObj = url.parse(request.url, true);
//static文件夾的絕對路徑
var staticPath = path.resolve(__dirname, 'static')
//獲取資源文件絕對路徑
var filePath = path.join(staticPath, pathObj.pathname)
if(filePath.indexOf('favicon.ico') === -1){//屏蔽瀏覽器默認對favicon.ico的請求
//同步讀取file
var fileContent = fs.readFileSync(filePath,'binary')
response.write(fileContent, 'binary')
}
response.end()
})
server.listen(8080)
console.log('visit http://localhost:8080')
瀏覽器中輸入的url為http://localhost:8080/login.html?aa=001&bb=002
request.url表示的是輸入的url除了域名后面的部分弧可,即為/login.html?aa=001&bb=002
url.parse(request.url, true)表示的是將該url解析成一個對象。其中第二個參數(shù)可省略劣欢,省略默認表示的是false棕诵。設(shè)置為true將使用查詢模塊分析查詢字符串,什么意思呢凿将?
解析后的對象中有個query的屬性年鸳,如下圖所示。
false的話丸相,query對應(yīng)的值=> 'aa=001&bb=002'
true的話,query對應(yīng)的值=>{ aa: '001', bb: '002' }
相當于將url中的參數(shù)進行了解析彼棍,以便后面的調(diào)用(url.parse(request.url, true).query.aa)
//request.url經(jīng)過url.parse(request.url, true)解析后的對象
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?aa=001&bb=002',
query: { aa: '001', bb: '002' },
pathname: '/login.html',
path: '/login.html?aa=001&bb=002',
href: '/login.html?aa=001&bb=002' }
- __dirname表示當前文件所在的目錄的絕對路徑(調(diào)用__dirname的文件灭忠,即myNodeServer.js所在路徑);__filename表示當前文件的絕對路徑座硕;process.cwd()返回運行當前腳本的工作目錄的路徑
- step3第一張圖片中可以見到我的html文件在static目錄下的弛作,讀文件readFile函數(shù)需要文件的一個完整路徑,通過path.resolve(__dirname, 'static')得到static文件夾的絕對路徑华匾。
- path.resolve()方法的作用相當于把第一個參數(shù)當成父目錄映琳,而把第二個參數(shù)當成子目錄或是其中的文件,進行解析之后得到一個新路徑蜘拉。之所這樣是因為linux等下的文件路徑和windows不一樣萨西,直接+'\static'拼接會有兼容性問題。
- path.join()用于連接路徑旭旭。該方法的主要用途在于谎脯,會正確使用當前系統(tǒng)的路徑分隔符,Unix系統(tǒng)是/持寄,Windows系統(tǒng)是\源梭。
step4
step3已經(jīng)可以展示相應(yīng)的html,css稍味,js等文件了废麻。但是多試驗幾次會發(fā)現(xiàn)幾個新的問題!DB烛愧!
①同步讀文件,如果文件很大的話,對后面代碼的執(zhí)行很不友好
②如果url中輸入的文件不存在的話屑彻,讀取不到文件验庙,導致服務(wù)器掛掉
因此,用異步讀取文件的方式來完善社牲。
var http = require('http')
var fs = require('fs')
var url = require('url')
var path = require('path')
var server = http.createServer(function(request, response){
//獲取輸入的url解析后的對象
var pathObj = url.parse(request.url, true);
//static文件夾的絕對路徑
var staticPath = path.resolve(__dirname, 'static')
//獲取資源文件絕對路徑
var filePath = path.join(staticPath, pathObj.pathname)
//異步讀取file
fs.readFile(filePath, 'binary', function(err, fileContent){
if(err){
console.log('404')
response.writeHead(404, 'not found')
response.end('<h1>404 Not Found</h1>')
}else{
console.log('ok')
response.write(fileContent, 'binary')
response.end()
}
})
})
server.listen(8080)
console.log('visit http://localhost:8080')