- 什么是靜態文件服務器?
- 個人理解就是網頁上沒有動態數據的變化,只有文件I/O操作在服務器
-
怎么樣?或者說原理?
- 首先,用戶從客戶端輸入文件地址,服務器端根據這個地址進行解析,所以 第一步應該是解析路由 ;
- 拿到路由之后就可以確定文件在磁盤的具體位置,就可以讀取文件流,所以 第二步是讀取文件流輸出到客戶端 。
- 那么,就先來做一個小demo:
1.首先,我們的項目目錄:
|-FirstNodeJs
|-node_moudles
|-public
|-----靜態資源(html,css,js,img,video..)
|-routers
|-routes.js
|-views
|-app.js
|-package.json
2. 接着我們在 app.js 寫上我們需要調用的方法:
// common.js 標准 使用的是require.js的管理客戶端模塊 // "use strict" //第一步獲取http協議 const myhttp = require("http"); const routes = require("./routes/routes.js") //引入路由模塊,以便在route層做分工 // 第二步 通過http協議創建服務器 const myserver = myhttp.createServer(function (req,res) { //響應瀏覽器 // console.log(request.url); var myPath = req.url; // console.log(myPath) var myNewPath = myPath.split("."); // console.log(myNewPath[1]); if(myNewPath[1]=="html"||myNewPath[1]=="css"||myNewPath[1]=="gif"||myNewPath[1]=="png"||myNewPath[1]=="jpg"||myNewPath[1]=="js"){ //這里做的是對靜態資源請求的攔截。 routes.sendInfo(res,myPath,myNewPath[1]) } })
// 第三步 監聽服務器
myserver.listen(8070,function () {
console.log("服務器已經啟動")
})
3. 在解析到這個路由過后,那么就可以文件流進行響應了,但是這里我們遇見一個問題即不同文件它的解析方式是不同的,比如js 它的解析就是text/javascript;而img請求呢
它將會是以圖片img/+圖片的類型進行解析 等;
所以我們就要考慮對代碼的封裝,因為他們的共同點都是返回給客戶端信息,不同點就只是它們的解析方式不同。那么我們應該考慮到npm 里有沒有朋友對這個進行過封裝呢?答案是有的,它就是--mime;
routers 文件路由層:
const myfs = require("fs") //// 該函數使用了fs這一文件模塊,用於提取文件里面的內容, 提取出來的內容(或錯誤)都會在回調函數傳回來,這也就是Node.js非阻塞I/O事件編程思想的體現 const mime = require("mime"); // 使用第三方mime模塊進行響應。 exports.sendInfo = function (res,myPath,myNewPath) { myfs.readFile("public"+myPath,function (err,data) { res.writeHead(200,{"content-type":mime.lookup(myNewPath)}) //這里就是我們想要的解析方式 res.write(data) res.end(); }) }
以上,就是我們的簡單方法即使用第三方插件mime,下面就寫一下一個便於理解的方法
1.app.js
const myhttp = require("http"); const routes = require("./routes/routes.js") // 第二步 通過http協議創建服務器 var myserver = myhttp.createServer(function (req,res) { var myPath = req.url; var myNewPath = myPath.split("."); if(myNewPath[1]=="html"){ routes.sendHtml(res,myPath,myNewPath[1]) // myfs.readFile("public"+myPath,"utf-8",function (err,data) { //下面注釋的代碼,其實就是沒有用routers這個模塊來進行拆分,是可以獨立運行的// // respones.writeHead(200,{"content-type":"text/html;charset=utf-8"}) // // console.log(data) // respones.write(data) // respones.end(); // }) } else if(myNewPath[1]=="css"){ routes.sendCss(res,myPath,myNewPath[1]) // myfs.readFile("public"+myPath,"utf-8",function (err,data) { // respones.writeHead(200,{"content-type":"text/css;charset=utf-8"}) // // console.log(data) // respones.write(data) // respones.end(); // }) } else if(myNewPath[1]=="gif"||myNewPath[1]=="png"||myNewPath[1]=="jpg"){ routes.sendImg(res,myPath,myNewPath[1]) // myfs.readFile("public"+myPath,function (err,data) { // respones.writeHead(200,{"content-type":"img/"+myNewPath[1]}) // // console.log(data) // respones.write(data) // respones.end(); // }) } else if(myNewPath[1]=="js"){ routes.sendJs(res,myPath,myNewPath[1]) // myfs.readFile("public"+myPath,"utf-8",function (err,data) { // respones.writeHead(200,{"content-type":"text/javascript;charset=utf-8"}) // respones.write(data) // respones.end(); // }) } }) myserver.listen(8070,function () { console.log("服務器已經啟動") })
2.routers 路由模塊文件
const myfs = require("fs") const mime = require("mime"); exports.sendHtml = function (res,myPath,myNewPath) { myfs.readFile("public"+myPath,"utf-8",function (err,data) { res.writeHead(200,{"content-type":"text/html;charset=utf-8"}) res.write(data) res.end(); }) } exports.sendJs = function (res,myPath,myNewPath) { myfs.readFile("public"+myPath,"utf-8",function (err,data) { res.writeHead(200,{"content-type":"text/javascript;charset=utf-8"}) res.write(data) res.end(); }) } exports.sendCss = function (res,myPath,myNewPath) { myfs.readFile("public"+myPath,"utf-8",function (err,data) { res.writeHead(200,{"content-type":"text/css;charset=utf-8"}) res.write(data) res.end(); }) } exports.sendImg = function (res,myPath,myNewPath) { myfs.readFile("public"+myPath,function (err,data) { res.writeHead(200,{"content-type":"img/"+myNewPath}) res.write(data) res.end(); }) }
總結,第一點,要清楚代碼流程,在app,js 那三步即1.先引入http 協議2.利用nodejs創建http服務器;3.監聽端口;
第二點,在實現demo時遇到的問題,文件的地址報錯就是在readfile()出錯;
引用文件時注意路徑;
第三點,時刻要分清楚app.js/routers.js數據流的走向,誰請求誰響應。