Node.js 移動端可訪問的靜態服務器
之前有用過一些別人寫的,要嘛太冗雜,要么有錯誤,還是自己搞一搞靠譜。
需求背景
之前開發環境用的是xampp的Apache和php的環境,因為公司服務器的語言是PHP的,有時要寫一些后臺,但是下載的一些前端lib框架庫文件沒有放在htdocs目錄下怕太亂。
有時要查看一些前端框架的源碼和example,file:///顯然是不行的,例如引入一個cdn的文件,或者頁面有ajax,就需要一個簡單的靜態服務器可以訪問這些文件。這個時候nodejs一個文件就可以搞定一個簡單的服務器就顯得十分合適。
系統環境:windows
基本思路:
-
http模塊創建服務器
-
url,path模塊解析url確定文件路徑
-
判斷請求的文件類型,返回不同的MIME類型(MIME類型不正確瀏覽器是不能正常解析的)
-
返回對應的資源
-
移動端真機測試訪問的處理
創建服務器
var
http = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs'),
os = require('os');
var server = http.createServer(function (req,res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.write('hello');
res.end();
})
server.listen('8080',function (){
console.log('server start');
})
服務器創建好了,可以訪問后,就要根據請求的url確定請求的文件路徑了。
處理請求文件路徑--簡單的路由
請求成功回調函數如下
var filename = __dirname+url.parse(req.url).pathname;
var resContentType = 'text/html';//返回資源的MIME類型
fs.exists(filename,function (exists){
if (!exists){
//文件不存在返回404
res.writeHead(404,{'Content-Type':'text/plain'});
res.write('404 Not Found');
res.end();
}else {
//文件存在讀取并返回
fs.readFile(filename,function (err,data){
if (err){
res.writeHead(500,{'Content-Type':'text/plain'});
res.end(err);
}else{
res.writeHead(200,{'Content-Type':resContentType});
res.write(data);
res.end();
}
})
}
})
這里我們先所有請求都返回html類型,這顯然是不行的,像css文件,js文件的MIME不是'text/html',所以要處理不同請求文件的MIME類型,這里我們加一個映射表。
注意: __dirname 一定要加上,單純的 url.parse(req.url).pathname 的路徑, fs.exists 是找不到的,永遠返回404。還有有的文章還有用 path.exists ...坑的好慘啊,path模塊根本沒有exists方法,要用fs模塊的。
處理不同文件類型的MIME
var mime = {
"html": "text/html",
"htm": "text/html",
"css": "text/css",
"js": "text/javascript",
"xml": "text/xml",
"json": "application/json",
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"png": "image/png",
"gif": "image/gif",
"bmp": "image/bmp",
"svg": "image/svg+xml",
"ico": "image/x-icon",
"mp3": "audio/mpeg",
"wav": "audio/x-wav",
"mp4": "video/mp4",
"swf": "application/x-shockwave-flash",
"woff": "application/x-font-woff"
}
這個表不一定全根據自己的需求添加即可。
回調函數里的部分就變成
var filename = __dirname+url.parse(req.url).pathname;
var extname = path.extname(filename);
//擴展名含點號如'.html',截掉
extname = extname ? extname.slice(1) : 'unknown';
//映射表中查找請求的資源的MIME類型并返回,沒有映射均返回'text/plain'類型
var resContentType = mime[extname] || 'text/plain';
移動端要可以訪問
其實這個與nodejs代碼并沒有必然的聯系,移動端訪問本機的兩個條件(服務器沒有請求限制的情況下,如apache需要修改一些配置文件):
-
把你的 localhost 改成 192.168.0.xxx
-
手機的網絡要與電腦在同一網段(如用的同一個WIFI)
當然也可以手動到cmd中ipconfig一下看看本機的ip地址,這里我額外加了os模塊用于獲取本機系統的ip,圖個方便,當然這個不是靜態服務器必須的要素。
最后的server.js的全部代碼也就很小的一段,就可以當靜態服務器了。復制一份扔在一些需要查看的文件夾的根目錄就可以充當小型服務器進行example瀏覽和測試了。
最后附上完整代碼:
var
http = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs'),
os = require('os');
function getIPv4(){
var interfaces = os.networkInterfaces();//獲取網絡接口列表
var ipv4s = [];//同一接口可能有不止一個IP4v地址,所以用數組存
Object.keys(interfaces).forEach(function (key){
interfaces[key].forEach(function (item){
//跳過IPv6 和 '127.0.0.1'
if ( 'IPv4' !== item.family || item.internal !== false )return;
ipv4s.push(item.address);//可用的ipv4s加入數組
console.log(key+'--'+item.address);
})
})
return ipv4s[0];//返回一個可用的即可
}
var mime = {
"html": "text/html",
"htm": "text/html",
"css": "text/css",
"js": "text/javascript",
"xml": "text/xml",
"json": "application/json",
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"png": "image/png",
"gif": "image/gif",
"bmp": "image/bmp",
"svg": "image/svg+xml",
"ico": "image/x-icon",
"mp3": "audio/mpeg",
"wav": "audio/x-wav",
"mp4": "video/mp4",
"swf": "application/x-shockwave-flash",
"woff": "application/x-font-woff"
}
var server = http.createServer(function (req,res){
var filename = __dirname+url.parse(req.url).pathname;
var extname = path.extname(filename);
//擴展名含點號如'.html',截掉
extname = extname ? extname.slice(1) : 'unknown';
//映射表中查找請求的資源的MIME類型并返回,沒有映射均返回'text/plain'類型
var resContentType = mime[extname] || 'text/plain';
fs.exists(filename,function (exists){
if (!exists){
//文件不存在返回404
res.writeHead(404,{'Content-Type':'text/plain'});
res.write('404 Not Found');
res.end();
}else {
//文件存在讀取并返回
fs.readFile(filename,function (err,data){
if (err){
res.writeHead(500,{'Content-Type':'text/plain'});
res.end(err);
}else{
res.writeHead(200,{'Content-Type':resContentType});
res.write(data);
res.end();
}
})
}
})
});
server.listen('8080',function (){
console.log('server start on: '+getIPv4()+':8080');
})
來自: https://segmentfault.com/a/1190000005927871