第六節(jié): 內(nèi)置模塊(二): HTTP模塊

1. 了解http協(xié)議

網(wǎng)絡(luò)是信息傳輸,接收,共享的虛擬平臺(tái),通過(guò)它把各個(gè)點(diǎn),面,體的信息聯(lián)系到一起,從而實(shí)現(xiàn)這些資源的共享
網(wǎng)絡(luò)傳輸數(shù)據(jù)有一定的規(guī)則,這些規(guī)則我們稱為協(xié)議,HTTP就是規(guī)則中的一種,而且使用最為頻繁是一種協(xié)議


1.1. 什么是http協(xié)議

http是網(wǎng)絡(luò)協(xié)議的一種,超文本傳輸協(xié)議(hypertext transfer protocol)的簡(jiǎn)寫
超文本傳輸協(xié)議傳輸?shù)膬?nèi)容就是超文本的標(biāo)記語(yǔ)言(文字,圖片,視頻,音頻...)
它是TCP/IP協(xié)議之上的一個(gè)應(yīng)用層協(xié)議,用于定義web瀏覽器與web服務(wù)器之間交換數(shù)據(jù)的過(guò)程以及數(shù)據(jù)本身的格式

HTTP協(xié)議是一種網(wǎng)絡(luò)傳輸協(xié)議,采用的是請(qǐng)求/應(yīng)答 方式傳遞數(shù)據(jù),一次請(qǐng)求對(duì)應(yīng)一次應(yīng)答(響應(yīng))



HTTP協(xié)議到底約束了什么?

  1. 約束了瀏覽器以何種格式向服務(wù)器端發(fā)送數(shù)據(jù)
  2. 約束了服務(wù)器應(yīng)該以何種格式來(lái)接受客戶端發(fā)送的數(shù)據(jù)
  3. 約束了服務(wù)器應(yīng)該以何種格式來(lái)反饋數(shù)據(jù)給瀏覽器
  4. 約束了瀏覽器應(yīng)該以何種格式來(lái)接受服務(wù)器反饋的數(shù)據(jù)


1.2 HTTP交互的特點(diǎn)

瀏覽器給服務(wù)器發(fā)送數(shù)據(jù): 一次請(qǐng)求
服務(wù)器給瀏覽器反饋數(shù)據(jù): 一次響應(yīng)
一次請(qǐng)求對(duì)應(yīng)一次響應(yīng),多次請(qǐng)求對(duì)應(yīng)多次響應(yīng)


1.3. HTTP狀態(tài)碼

什么是http狀態(tài)碼?

http協(xié)議規(guī)定的服務(wù)器響應(yīng)數(shù)據(jù)時(shí)的狀態(tài)編碼,就是狀態(tài)碼



常用的狀態(tài)碼

  1. 1xx : 表示普通消息,沒(méi)有特殊含義
  2. 2xx : 服務(wù)器響應(yīng)成功
  • 200 成功 [重點(diǎn)掌握]
  1. 3xx : 表示重定向
  • 301 永久重定向 [重點(diǎn)掌握]
  • 302 臨時(shí)重定向
  • 304 使用緩存(服務(wù)器沒(méi)有更新過(guò))
  1. 4xx : 表示請(qǐng)求失敗
  • 403 權(quán)限不足,無(wú)法訪問(wèn)
  • 404 資源找不到 [重點(diǎn)掌握]
  1. 5xx 服務(wù)器執(zhí)行有錯(cuò)
  • 500 服務(wù)器代碼有錯(cuò)
  • 502 網(wǎng)關(guān)或代理服務(wù)器有錯(cuò)
  • 503 服務(wù)器崩潰了



狀態(tài)碼的使用

res.writeHead(狀態(tài)碼,響應(yīng)頭)


1.4. 響應(yīng)頭


1.4.1 響應(yīng)的文件類型 Content-Type:
  1. text/html;charset=utf-8 (如果為指定文件類型,默認(rèn)就是html)

    字符編碼,node默認(rèn)的字體編碼編碼是utf-8,瀏覽器的編碼,默認(rèn)是系統(tǒng)編碼,簡(jiǎn)體中文編碼,就是gbk編碼,所有會(huì)出現(xiàn)亂碼


1.4.2 響應(yīng)的內(nèi)容的長(zhǎng)度 Content-Length:
  1. 值是數(shù)字, 字節(jié)的 長(zhǎng)度,一般不設(shè)置,返回的內(nèi)容是多少就是多少


1.4.3 解決跨域的響應(yīng)頭設(shè)置 Access-Control-Allow-Origin

可以通過(guò)這個(gè)響應(yīng)頭解決跨域問(wèn)題,值為*

 res.writeHead(200, {
    "Content-Type": "text/html;charset=utf-8",
    "Access-Control-Allow-Origin": "*"
  });
  res.end("<h1>今天星期幾</h2>")


1.5. HTTP 響應(yīng)不同的數(shù)據(jù)類型

什么是MIME類型

? MIME類型可以理解為是文件類型的表述

服務(wù)器具有返回各種數(shù)據(jù)的能力,但是返回的數(shù)據(jù)時(shí),應(yīng)告訴瀏覽器返回的是一個(gè)什么類型的文件

HTTP中使用MIME 類型代表文件的類型

文件 MIME類型
html text/html
jpg image/jpg
png image/png
 res.writeHead(200, {
    "Content-Type": "text/plain;charset=utf-8",
    "Access-Control-Allow-Origin": "*"
  });
  res.end("<h1>今天星期幾</h2>")


2. HTTP模塊

http 模塊時(shí)一個(gè)在 nodejs 中用于網(wǎng)絡(luò)通信的模塊


2.1. NodeJS服務(wù)器

利用Http模塊創(chuàng)建服務(wù)器

2.1.1 創(chuàng)建服務(wù)對(duì)象

導(dǎo)入http模塊, 并創(chuàng)建服務(wù)對(duì)象

const http = require("http")
const server = http.createServer()


2.1.2 創(chuàng)建請(qǐng)求處理函數(shù)

有兩種方法,

第一種方法是在創(chuàng)建服務(wù)對(duì)象是通過(guò)回調(diào)函數(shù)的方式

http.createServer((req,res) => {
    res.end("Hello World")
})

第二種方法,通過(guò)綁定request事件處理函數(shù)

server.on("request", (req,res) => {
    res.end("Hello World")
})


2.1.3 設(shè)置服務(wù)器監(jiān)聽(tīng)

通過(guò)listen 方法設(shè)置服務(wù)器監(jiān)聽(tīng),

listen方法接受4個(gè)參數(shù)

server.listen(port [, host] [,backlog] [, callback])

  1. prot 必需的 監(jiān)聽(tīng)的端口號(hào)
  2. host 可選的 監(jiān)聽(tīng)指定的地址(一般省略)
  3. backlog 可選, 參數(shù)是一個(gè)指定等待客戶端連接的最大數(shù)量, 默認(rèn)511( 一般不使用)
  4. callback 可選, 用于在服務(wù)器監(jiān)聽(tīng)啟動(dòng)成功后執(zhí)行的回調(diào)函數(shù)
server.listen(3000)

listen方法的callback參數(shù)也可以單獨(dú)去處理,因?yàn)榉?wù)器監(jiān)聽(tīng)啟動(dòng)成功后,會(huì)自動(dòng)觸發(fā)listening事件,那么我們就可以通過(guò)綁定listening事件在事件的回調(diào)函數(shù)里處理

server.on("listening", function(){
    console.log(1)
})


1.4 例子
// 引入http通信模塊
var http = require('http');

// 創(chuàng)建服務(wù)器
var server = http.createServer()

server.on("request",function (req, res) {
   // req: 請(qǐng)求對(duì)象,包含了所有客戶端請(qǐng)求的數(shù)據(jù),請(qǐng)求頭,請(qǐng)求主體
   // res: 響應(yīng)對(duì)象,包含了所有服務(wù)器端發(fā)送給客戶端的數(shù)據(jù),響應(yīng)投,響應(yīng)主體
   // req,res 數(shù)據(jù)都是流的形式
   // res.write("hello world");  采用流的方式傳輸,記得end()結(jié)束
  res.setHeader("Content-Type", "text/html;charset=utf-8")
  res.end("<h1>這是自己的淘寶</h1>"
})

// 監(jiān)聽(tīng)端口號(hào)
server.listen(80, function () {
  console.log("服務(wù)器啟動(dòng)成功")
})

我們也可以通過(guò)回調(diào)函數(shù)來(lái)處理


// 獲取內(nèi)置的模塊http,這個(gè)模塊是用來(lái)創(chuàng)建服務(wù)器的
const http = require('http');

// 創(chuàng)建一個(gè)服務(wù)器
const server = http.createServer(function (req, res) {
  res.end('<h1>這是一個(gè)node(3+4)開(kāi)發(fā)的服務(wù)器</h1>')
})

// 監(jiān)聽(tīng)端口
server.listen(3000)

如果出現(xiàn)亂碼,可以設(shè)置響應(yīng)頭解決

// 這是設(shè)置響應(yīng)頭,防止出現(xiàn)亂碼(兩種方法都可以)
// res.writeHead(200, { 'Content-Type': 'text/html;charset=UTF-8' });
res.setHeader('Content-Type', 'text/html;charset=UTF-8');

Node.js沒(méi)有根目錄的概念


2.1.5 關(guān)閉服務(wù)器

通過(guò)close方法關(guān)閉服務(wù)器

server.close()

在服務(wù)器被關(guān)閉的時(shí)候會(huì)觸發(fā)close事件, 所以我們可以通過(guò)綁定close事件來(lái)處理在服務(wù)器關(guān)閉的時(shí)候要做的事情

server.on("close", function(){
    console.log("close")
})


2.2. 獲取客戶端請(qǐng)求信息

在接受到客戶端發(fā)送的請(qǐng)求時(shí),調(diào)用的回調(diào)函數(shù)第一個(gè)參數(shù)值是一個(gè)httpInconmingMessage對(duì)象, 該對(duì)象是用于讀取客戶端請(qǐng)求流中的數(shù)據(jù)

server.on("request", (req,res) => {
    console.log(req)
    res.end("數(shù)據(jù)")
})


請(qǐng)求對(duì)象常用的屬性
  1. method 屬性,

    值是一個(gè)字符串, 為客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí)使用的的方法, 常用的強(qiáng)求有"GET","POST","PUT","DETELE"

    server.on("request", (req,res) => {
        console.log(req.method) // 打印請(qǐng)求方式
    })
    
  2. url 屬性

    url 屬性值為客戶端發(fā)送請(qǐng)求時(shí)使用URL參數(shù)字符串

    server.on("request", (req,res) => {
        console.log(req.url)
    })
    

    我們可以根據(jù)用戶請(qǐng)求的路徑不同 相應(yīng)不同 的內(nèi)容

  3. headers 屬性

    該屬性值為客戶端發(fā)送的請(qǐng)求頭,其中存放了客戶端發(fā)送的所有請(qǐng)求信息,包括cookie 信息及瀏覽器信息

    server.on("request", (req,res) => {
        console.log(req.headers)
    })
    


2.3. HTTP響應(yīng)的內(nèi)容

在接受到用戶請(qǐng)求的回調(diào)函數(shù)或request事件處理函數(shù)中的第二個(gè)參數(shù)值是一個(gè)http.ServerResponse對(duì)象, 可以利用該對(duì)象發(fā)送內(nèi)容給客戶端,及服務(wù)器端的響應(yīng)流

server.on("request", (req,res) => {
    console.log(res)
    res.end("數(shù)據(jù)")
})


2.3.1 響應(yīng)對(duì)象常用的屬性
  1. writeHead : 設(shè)置有狀態(tài)碼的響應(yīng)頭信息
  2. setHeader: 設(shè)置單個(gè)響應(yīng)頭字段
  3. write: 發(fā)送響應(yīng)數(shù)據(jù)
  4. end : 結(jié)束響應(yīng)


2.3.2 可以利用writeHead方法來(lái)發(fā)送響應(yīng)頭
1. writeHead方法接受三個(gè)參數(shù)
  1. statusCode 第一個(gè)參數(shù), 必須傳遞, 執(zhí)行一個(gè)http 狀態(tài)碼 例如200
  2. reasonPhrase 第二個(gè)參數(shù)可選,就是對(duì)狀態(tài)碼的描述信息,是一個(gè)字符串,一般不使用
  3. headers 第三個(gè)參數(shù)是可選的, 參數(shù)值是一個(gè)對(duì)象,用來(lái)配置響應(yīng)頭信息
server.on("request", (req,res) => {

    // 設(shè)置響應(yīng)頭信息
    res.writeHead(200,'ok',{
        'Content-Type': 'text/html;charset=utf8'
    })

    res.end("響應(yīng)數(shù)據(jù)")
})


2. 響應(yīng)頭常用的字段
  1. content-type: 指定響應(yīng)內(nèi)容的的類型
  2. location : 用于將客戶端重定向到另外一個(gè)ur l地址
  3. set-cookie: 用于在客戶端創(chuàng)建cookie
  4. access-control-allow-origin: 解決跨域問(wèn)題
 res.writeHead(200,{
        'Content-Type': 'text/html;charset=utf8',
        'Set-Cookie': 'name=wuwei;age=1*60*60*1000'
    })


2.3.3 setHeader 設(shè)置響應(yīng)頭

接受兩個(gè)參數(shù)

  1. name: 響應(yīng)頭的字段
  2. value: 響應(yīng)頭的值
 res.setHeader('Content-Type', 'text/html;charset=utf8')

兩個(gè)方法對(duì)比

setHeader 每次只能設(shè)置一個(gè)響應(yīng)頭字段, writeHead可以一次設(shè)置多個(gè)響應(yīng)頭字段


2.3.4 write 方法

write 方法 發(fā)送響應(yīng)內(nèi)容,可以多次調(diào)用

server.on("request", (req,res) => {
    res.setHeader('Content-Type', 'text/html;charset=utf8')

    res.write("響應(yīng)數(shù)據(jù)")
    res.write("響應(yīng)數(shù)據(jù)2")
    res.write("響應(yīng)數(shù)據(jù)3")
  
})


2.3.5 end 方法

end 方法, 在每次數(shù)據(jù)發(fā)送完畢后通過(guò)end方法來(lái)結(jié)束響應(yīng)

server.on("request", (req,res) => {
    res.setHeader('Content-Type', 'text/html;charset=utf8')

    res.write("響應(yīng)數(shù)據(jù)")
    res.write("響應(yīng)數(shù)據(jù)2")
    res.write("響應(yīng)數(shù)據(jù)3")
  
    // 結(jié)束響應(yīng)
    res.end()
})

同時(shí)我們也可以給end傳參數(shù),表示在結(jié)束響應(yīng)的時(shí)候最后一次給客戶端響應(yīng)的內(nèi)容

server.on("request", (req,res) => {
    res.setHeader('Content-Type', 'text/html;charset=utf8')
  
    // 結(jié)束響應(yīng)
    res.end("響應(yīng)內(nèi)容")
})


3. 熱更新

我們發(fā)現(xiàn)每一次修改都需要從新打斷,重新用node啟動(dòng),如果不希望這樣,就可以使用熱更新.

下載nodemon 包

npm i -g nodemon

安裝完成后就可以用nodemon替代node啟動(dòng)

nodemon app.js
//啟動(dòng)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市最楷,隨后出現(xiàn)的幾起案子陆赋,更是在濱河造成了極大的恐慌临梗,老刑警劉巖度陆,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡绪氛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門涝影,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)枣察,“玉大人,你說(shuō)我怎么就攤上這事燃逻⌒蚰浚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵伯襟,是天一觀的道長(zhǎng)猿涨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)姆怪,這世上最難降的妖魔是什么叛赚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮稽揭,結(jié)果婚禮上俺附,老公的妹妹穿的比我還像新娘。我一直安慰自己淀衣,他們只是感情好昙读,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著膨桥,像睡著了一般蛮浑。 火紅的嫁衣襯著肌膚如雪唠叛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天沮稚,我揣著相機(jī)與錄音艺沼,去河邊找鬼。 笑死蕴掏,一個(gè)胖子當(dāng)著我的面吹牛障般,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盛杰,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼挽荡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了即供?” 一聲冷哼從身側(cè)響起定拟,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逗嫡,沒(méi)想到半個(gè)月后青自,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驱证,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年延窜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抹锄。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逆瑞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出祈远,到底是詐尸還是另有隱情呆万,我是刑警寧澤商源,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布车份,位于F島的核電站,受9級(jí)特大地震影響牡彻,放射性物質(zhì)發(fā)生泄漏扫沼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一庄吼、第九天 我趴在偏房一處隱蔽的房頂上張望缎除。 院中可真熱鬧,春花似錦总寻、人聲如沸器罐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轰坊。三九已至铸董,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肴沫,已是汗流浹背粟害。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颤芬,地道東北人悲幅。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像站蝠,于是被迫代替她去往敵國(guó)和親汰具。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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