1. 程式人生 > >如何創建一個基於Node的HTTP服務器

如何創建一個基於Node的HTTP服務器

eth utf-8 span 不同類 第三方 ice .com charset 依據

首先創建一個HTTP服務器。

var http = require(‘http‘);

function serve(request,response) {
    console.log(request.method);    //請求的方法
    console.log(request.url);  //請求裏的url,只含有路徑名,並不是完整的url
    console.log(request.header) //獲取請求頭

    response.statusCode = 200;  
    //設置響應類型,編碼為utf-8。
    //服務器返回資源給瀏覽器時,還應該告訴瀏覽器這是什麽類型的文件,以什麽方式解析。不指定的話可能會造成亂碼
response.setHeader(‘Content-Type‘,‘text/html;charset=utf-8‘); response.setHeader(‘name‘,‘zfpx‘); response.write(new Date().toString()); response.end(); } var server = http.createServer(serve); server.listen(3000);

如果我們希望讀取其他文件的內容,則需要先導入fs模塊,該模塊是讀取文件的模塊

var fs = require(‘fs‘);

function
serve(request,response) { var url = request.url;//設置響應類型,編碼為utf-8。 //服務器返回資源給瀏覽器時,還應該告訴瀏覽器這是什麽類型的文件,以什麽方式解析 response.setHeader(‘Content-Type‘,‘text/html;charset=utf-8‘); //如果我們希望返回的是其他文件的內容,則需要先讀取其他文件,這時需要fs模塊來讀取文件 fs.readFile(‘index.html‘,function(err,data) { response.write(data); response.end(); }) }

但是這樣又有一個問題,就是:在對返回的HTML代碼開始解析時,解析過程中如果遇到引用的服務器上的資源(額外的CSS,JS代碼,圖片等資源),需要再次向服務器發送請求,但是不管是發送什麽請求,服務器返回的都是index.html文件。這時,我們就需要對不同的請求資源做一個判斷,讓其返回不同類型的資源。

function serve(request,response) {
    var url = request.url;
    if (url == ‘/‘) {
        //設置響應類型,編碼為utf-8。
        //服務器返回資源給瀏覽器時,還應該告訴瀏覽器這是什麽類型的文件,以什麽方式解析
        response.setHeader(‘Content-Type‘,‘text/html;charset=utf-8‘);
        //如果我們希望返回的是其他文件的內容,則需要先讀取其他文件,這時需要fs模塊來讀取文件
        fs.readFile(‘index.html‘,function(err,data) {
            response.write(data);
            response.end();
        })
    }else if (url == ‘/style.css‘) {
        response.setHeader(‘Content-Type‘,‘text/css;charset=utf-8‘);
        //如果我們希望返回的是其他文件的內容,則需要先讀取其他文件,這時需要fs模塊來讀取文件
        fs.readFile(‘style.css‘,function(err,data) {
            response.write(data);
            response.end();
        })
    }

一個頁面裏,我們可能會請求非常多的靜態資源,如果每次都加一個else if 顯然讓頁面更復雜,且不利於維護。所以我們希望將所有的靜態資源請求都封裝在一個函數裏。

function parseMime(pathname) {
    var reg = /\.(HTML|JS|CSS|JSON|TXT|ICO|JPG)/i;
    if (reg.test(pathname)) {
        //獲取請求文件的後綴名
        var suffix = reg.exec(pathname)[1].toUpperCase();
        //根據請求文件的後綴名獲取到當前文件的MIME類型
        var suffixMIME = "text/plain";
        switch(suffix) {
            case "HTML":
                suffixMIME = "text/html";
                break;
            case "CSS":
                suffixMIME = "text/css";
                break;
            case "JS":
                suffixMIME = "text/javascript";
                break;
            case "JSON":
                suffixMIME = "application/json";
                break;
            case "ICO":
                suffixMIME = "application/octet-stream";
                break;
            case "JPG":
                suffixMIME = "image/jpg";
                break;
            
        }
    }
    return suffixMIME;
}

實際上,Node中還提供了一個第三方的模塊能夠自動幫我們判斷文件的MIME類型,我們這裏還需要用到一個第三方的模塊"mine"。

var mime = require(‘mime‘);

function serve(request,response) {
    var url = request.url;
    if (url == ‘/‘) {
        //設置響應類型,編碼為utf-8。
        //服務器返回資源給瀏覽器時,還應該告訴瀏覽器這是什麽類型的文件,以什麽方式解析
        response.setHeader(‘Content-Type‘,‘text/html;charset=utf-8‘);
        //如果我們希望返回的是其他文件的內容,則需要先讀取其他文件,這時需要fs模塊來讀取文件
        fs.readFile(‘index.html‘,function(err,data) {
            response.write(data);
            response.end();
        })
    }else{
        static(url,response)
    }    
}

function static(url,response) {
    response.setHeader(‘Content-Type‘,mime.lookup(url) + ‘;charset=utf-8‘);
    //如果我們希望返回的是其他文件的內容,則需要先讀取其他文件,這時需要fs模塊來讀取文件
    fs.readFile(url.slice(1),function(err,data) {
        response.write(data);
        response.end();
    })
    
}

現在我們的url都是類似http://localhost:3000/index.html這樣的,就是客戶端只是單純的獲取數據,並不涉及向服務器端發送數據。

前面我們說過,request.url獲取的是‘3000:‘之後的內容,那麽當我們需要向服務器傳一些內容的時候,比如說http://localhost:3000/index.html/?name="xiaoyu"。這時request.url獲取的就是/index.html/?name="xiaoyu"。

這樣的url顯然不能再作為我們判斷路徑的依據,所以我們得進一步處理這個url。其實node提供了一個更加強大的url解析庫給我們,這個庫就是”url“。這個庫能夠解析整個完整的url路徑。

傳送地址:url模塊學習小結

如何創建一個基於Node的HTTP服務器