Node-http模塊

一棚品、使用 Node 構(gòu)建 web 應(yīng)用

  1. PHP是后端的網(wǎng)站開發(fā)語言蚜迅,PHP 開發(fā)出來的網(wǎng)站捎泻,可以通過 Apache 服務(wù)器托管運行起來;
  2. Node中诡曙,可以使用 Javascript 編寫后端網(wǎng)站臀叙,沒有類似于 Apache 這樣的服務(wù)器軟件,來提供對應(yīng)的網(wǎng)站服務(wù)价卤。所以需要手動編寫一個劝萤。

二、B/S 交互模型

什么是B/S:特指基于 瀏覽器(Browser) 和 服務(wù)器(Server) 這種交互形式慎璧;

  1. 什么是服務(wù)器:在網(wǎng)絡(luò)節(jié)點中床嫌,專門對外提供資源服務(wù)的一臺電腦;
  2. 什么是客戶端:在網(wǎng)絡(luò)節(jié)點中炸卑,專門用來消費服務(wù)的一臺電腦既鞠;
  3. HTTP 協(xié)議的通信模型:請求 - 處理 - 響應(yīng)的過程煤傍;
    • 請求:由客戶端發(fā)起請求盖文;
    • 處理:由服務(wù)器端處理請求;
    • 響應(yīng):服務(wù)器端把處理的結(jié)果蚯姆,通過網(wǎng)絡(luò)發(fā)送給客戶端五续;
  4. 什么是靜態(tài)資源:服務(wù)器端只需要讀取并直接發(fā)送給客戶端、不需要進(jìn)一步處理的資源龄恋,叫做靜態(tài)資源疙驾;
  5. 什么是動態(tài)資源:服務(wù)器端沒有現(xiàn)成的資源,需要服務(wù)器端動態(tài)生成的資源郭毕,叫做動態(tài)資源它碎;

三、實現(xiàn)一個類似于Apache的 靜態(tài)資源服務(wù)器

使用http核心模塊,創(chuàng)建最基本的web服務(wù)器

1. 創(chuàng)建最基本的web服務(wù)器

  • 導(dǎo)入http模塊:const http = require("http")扳肛;
  • 創(chuàng)建服務(wù)器:使用 const server = http.createServer() 創(chuàng)建服務(wù)器傻挂;
  • 綁定監(jiān)聽事件:通過 server.on('request', function(req, res) { 請求的處理函數(shù) }) 綁定事件 并 指定 處理函數(shù);
  • 啟動服務(wù)器:通過 server.listen(端口, IP地址, 啟動成功的回調(diào)函數(shù)) 來啟動服務(wù)器挖息;
  • res.end() 向客戶端發(fā)送內(nèi)容
// 導(dǎo)入http核心模塊
const http = require("http");
// 創(chuàng)建服務(wù)器
const server = http.createServer();
// 綁定request事件,監(jiān)聽客戶端請求
server.on("request", function(req, res) {
    // end方法向客戶端發(fā)送內(nèi)容
    res.end("hello world");
});
// 啟動服務(wù)器
server.listen(3000, "127.0.0.1", function() {
    console.log("server running at http://127.0.0.1:3000");
});

2. 防止響應(yīng)內(nèi)容中文亂碼問題

  • 通過 設(shè)置響應(yīng)報文頭的 Content-Type金拒,來指定響應(yīng)內(nèi)容的編碼類型,從而防止亂碼:
    res.writeHeader(200, {
    'Content-Type': 'text/plain; charset=utf-8'
    })

3. 根據(jù)不同的URL返回不同的文本內(nèi)容

  • 使用 req.url 獲取客戶端請求的URL地址
  • res.writeHeader() 指定編碼格式
server.on('request', function(req, res) {
    const url = req.url
    // 防止中文亂碼
    res.writeHeader(200, {
        //  text/plain 和 text/html的區(qū)別: plain表示普通的文本字符串套腹; html 表示以 HTMl 標(biāo)簽的形式去解析服務(wù)器返回的內(nèi)容
        // image/jpg绪抛、image/gif、image/png
        'Content-Type': 'text/plain; charset=utf-8'
    })
    if (url === '/' || url === '/views/index.html') {
        res.end('首頁')
    } else if (url === '/views/movie.html') {
        res.end('電影')
    } else if (url === '/views/about.html') {
        res.end('關(guān)于')
    } else {
        res.end('請求的內(nèi)容不存在电禀!')
    }
})

4. 根據(jù)不同的URL返回不同的HTML頁面

  • 主要思路:使用 fs 模塊 讀取URL對應(yīng)的HTML頁面內(nèi)容幢码,并使用 res.end() 響應(yīng)給客戶端即可;
const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer()
server.on('request', function(req, res) {
    const url = req.url
    // TODO: 判斷請求的URL地址鞭呕,返回對應(yīng)的HTML頁面內(nèi)容
    if (url === '/' || url === '/views/index.html') {
        // 返回首頁頁面
        // 1. 使用 fs 模塊蛤育,讀取 首頁文件
        // 2. 把讀取到的首頁,通過 res.end 返回即可
        fs.readFile(path.join(__dirname, './views/index.html'), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/views/movie.html') {
        // 返回電影頁面
        fs.readFile(path.join(__dirname, './views/movie.html'), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/views/about.html') {
        // 返回關(guān)于頁面
        fs.readFile(path.join(__dirname, './views/about.html'), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/css/1.css') {
    // 讀取樣式表
    fs.readFile(path.join(__dirname, '/css/1.css'), (err, buf) => {
      if (err) return res.end('404. Not found.')
      res.end(buf)
    })
  } else if (url === '/js/1.js') {
    // 讀取 JS 文件
    fs.readFile(path.join(__dirname, '/js/1.js'), (err, buf) => {
      if (err) return res.end('404. Not found.')
      res.end(buf)
    })
  }
})

5. 處理并返回css樣式表

6. 處理并返回Javascript文件

7. 優(yōu)化

// res.end() 方法葫松,接收兩種類型的數(shù)據(jù)  String  瓦糕,二進(jìn)制類型的數(shù)據(jù)
// 網(wǎng)絡(luò)傳輸?shù)臅r候是二進(jìn)制數(shù)據(jù),所以可以省略第二個參數(shù)腋么,dataStr為二進(jìn)制數(shù)據(jù)
// 直接給res.end()方法傳入二進(jìn)制數(shù)據(jù)的話咕娄,就省了一步轉(zhuǎn)碼。
fs.readFile(path.join(__dirname, './views/about.html'), (err, dataStr) => {
    if (err) return res.end('404. Not found.')
    res.end(dataStr)
})

客戶端請求任何資源珊擂,服務(wù)器處理后客戶端才能拿到

監(jiān)聽請求代碼可以優(yōu)化為:

server.on('request', function(req, res) {
    const url = req.url
        // TODO: 判斷請求的URL地址圣勒,返回對應(yīng)的HTML頁面內(nèi)容
    if (url === '/' || url === '/views/index.html') {
        // 返回首頁頁面
        // 1. 使用 fs 模塊,讀取 首頁文件
        // 2. 把讀取到的首頁摧扇,通過 res.end 返回即可
        fs.readFile(path.join(__dirname, url), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/views/movie.html') {
        // 返回電影頁面
        fs.readFile(path.join(__dirname, url), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/views/about.html') {
        // 返回關(guān)于頁面
        fs.readFile(path.join(__dirname, url), 'utf-8', (err, dataStr) => {
            if (err) return res.end('404. Not found.')
            res.end(dataStr)
        })
    } else if (url === '/css/1.css') {
        // 讀取樣式表
        fs.readFile(path.join(__dirname, url), (err, buf) => {
            if (err) return res.end('404. Not found.')
            res.end(buf)
        })
    } else if (url === '/js/1.js') {
        // 讀取 JS 文件
        fs.readFile(path.join(__dirname, url), (err, buf) => {
            if (err) return res.end('404. Not found.')
            res.end(buf)
        })
    }
})

進(jìn)一步優(yōu)化, 去掉重復(fù)代碼:

server.on('request', function(req, res) {
    let url = req.url

    // TODO: 判斷請求的URL地址圣贸,返回對應(yīng)的HTML頁面內(nèi)容
    // 單獨處理根目錄
    if (url === '/') url = '/views/index.html'
    fs.readFile(path.join(__dirname, url), (err, buf) => {
        if (err) return res.end('404. Not found.')
        res.end(buf)
    })
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扛稽,隨后出現(xiàn)的幾起案子吁峻,更是在濱河造成了極大的恐慌,老刑警劉巖在张,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件用含,死亡現(xiàn)場離奇詭異,居然都是意外死亡帮匾,警方通過查閱死者的電腦和手機(jī)啄骇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瘟斜,“玉大人缸夹,你說我怎么就攤上這事痪寻。” “怎么了虽惭?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵槽华,是天一觀的道長。 經(jīng)常有香客問我趟妥,道長猫态,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任披摄,我火速辦了婚禮亲雪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疚膊。我一直安慰自己义辕,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布寓盗。 她就那樣靜靜地躺著灌砖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪傀蚌。 梳的紋絲不亂的頭發(fā)上基显,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機(jī)與錄音善炫,去河邊找鬼撩幽。 笑死,一個胖子當(dāng)著我的面吹牛箩艺,可吹牛的內(nèi)容都是我干的窜醉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼艺谆,長吁一口氣:“原來是場噩夢啊……” “哼榨惰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起静汤,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤琅催,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后撒妈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恢暖,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡排监,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年狰右,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舆床。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡棋蚌,死狀恐怖嫁佳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谷暮,我是刑警寧澤蒿往,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站湿弦,受9級特大地震影響瓤漏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颊埃,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一蔬充、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧班利,春花似錦饥漫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闯割,卻和暖如春彻消,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宙拉。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工证膨, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鼓黔。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓央勒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親澳化。 傳聞我的和親對象是個殘疾皇子崔步,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容