node實現封裝伺服器靜態檔案處理
先給自己一個做這的理由##
很多小夥伴們可能會問,問什麼要這樣去做呢,express,koa不是已經做的很好了嗎?我實際上也想這麼回答。但是我總覺得有點不妥。很多的框架固然已經做的很好了。但是如果沒有人去追根溯源的話這個東西怎麼能越做越好呢。很多做技術的人習慣性的直接拿來去用。對於開發來說固然很nice。但對自身就我個人而言就捨本諑末了。解釋完畢至少我自己覺得還行。
我老老實實從底層開始寫防止以後久了忘了。
實現思路
通過http請求中不同的路徑名去對應的靜態檔案區域讀取對應的檔案直接返回給客戶端。
1.做一下前期準備工作。 這個簡單不用太複雜跟著來就行。
2.建立專案資料夾
3.在資料夾中新增app.js 作為入口檔案
4.建立靜態資料夾 static 其中寫一個簡單的佈局index.html,可以在其中引入css,js,與圖片檔案但是路徑要對。
5.開始寫。
1.首先搭建http服務,得到客戶端的請求路徑
var http = require('http');
http.createServer(function(req,res){
console.log(req.url);
res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});
res.end("你好 node");
}).listen(8000);
/*
1.至少可以說這個東西是最簡單的。
2.此時我們就可以去訪問這個 localhost:8000/index.html 了。
3. 直接列印 "/index","/favicon.ico" 至於問什麼是倆我就不解釋了。
4.再一次訪問 localhost:8000/index.html?asd 發現列印 "index.html?asd"
*/
通過上面的程式碼我們發現了我們可以直接從req.url中直接拿到訪問的路徑。但是兩種情況下 /favicon.ico 與後面的引數不是我們需要的, 對於 /favicon.ico 可以直接用 if 判斷後過濾。而對於引數我們只能引入 url 模組了。
var http = require('http'),
url = require('url')
http.createServer(function (req,res){
// 獲取所需要的路徑
var pathname = url.parse(req.url).pathname;
if( pathname !="/favicon.ico"){
console.log(pathname);
}
res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"})
res.end("你好 node");
}).listen(8000,function(){
console.log("server is start");
});
/*
這次列印的一定是你想要的內容
*/
2.得到對應的檔案返回
得到了對應的路徑呢 , 我們此時就需要通過路徑讀取檔案 , 返回給客戶端對應的檔案了。此時就需要用到fs模組了。
var http = require('http'),
url = require('url'),
fs = require('fs')
http.createServer(function(req,res){
// 獲取所需要的路徑
var pathname = url.parse(req.url).pathname;
if( pathname !="/favicon.ico"){
//開始讀取檔案並返回
fs.readFile('static'+pathname,function(err,data){
if(err){
console.log(err);
return false;
}
// 非同步 I/O分阻塞,耗時。所以提上來。
res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});
res.write(data);
res.end();
})
}
}).listen(8000,function(){
console.log("server is start");
});
// 去訪問一下 localhost:8000/index.html
這會兒你會發現你的 html 正常顯示 , 但是css , 與 js 已經載入卻並沒有被應用。這也是我第一次踩的坑。 如果仔細一點的話, 可以看到我的 content-type錯了。所有的都是 text/html。但是css應該是 text/css 。javascript應該是 text/javascript。 為此我們如果寫一個方法,拿到對應的檔案字尾名,並且已合適的 content-type 型別呢。試試看!!
var path = require('path');
module.exports = function(pathname){
pathname = path.extname(pathname);
switch (pathname){
case ".html":
return "text/html";
case ".css":
return "text/css";
case ".js":
return "text/javaScript"
default:
return "text/html";
}
}
然後在 app的檔案中載入這個檔案。直接將 Content-Type 中內容替換。 頁面就可以正常載入了。css 與js檔案也變得可用。
一隻坑
心細的同學會發現有一點不對的地方。就是這樣的話圖片的content-type也不對,別的檔案也沒有處理。 這樣就說明這個程式碼有個大坑。
那麼怎樣解決呢?
有心的同學們可以搜一下所有檔案的字尾名以及對應的content-type 做成json檔案可以引入通過對應邏輯便可以實現。剩下的稍微動點腦子就可做出來了。 就寫到這了
結尾
最後需要做的就是將它封裝成好看,易用的樣子。 自己可以試試哦每個人有自己方式。就不寫了。