Node.js 移動端可訪問的靜態服務器

以前有用過一些別人寫的,要嘛太冗雜,要麼有錯誤,仍是本身搞一搞靠譜。javascript

需求背景

以前開發環境用的是xampp的Apache和php的環境,由於公司服務器的語言是PHP的,有時要寫一些後臺,可是下載的一些前端lib框架庫文件沒有放在htdocs目錄下怕太亂。php

有時要查看一些前端框架的源碼和example,file:///顯然是不行的,例如引入一個cdn的文件,或者頁面有ajax,就須要一個簡單的靜態服務器能夠訪問這些文件。這個時候nodejs一個文件就能夠搞定一個簡單的服務器就顯得十分合適。css

系統環境:windowshtml

基本思路:前端

  1. http模塊建立服務器java

  2. url,path模塊解析url肯定文件路徑node

  3. 判斷請求的文件類型,返回不一樣的MIME類型(MIME類型不正確瀏覽器是不能正常解析的)ajax

  4. 返回對應的資源apache

  5. 移動端真機測試訪問的處理json

建立服務器

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');
})
相關文章
相關標籤/搜索