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é)議到底約束了什么?
- 約束了瀏覽器以何種格式向服務(wù)器端發(fā)送數(shù)據(jù)
- 約束了服務(wù)器應(yīng)該以何種格式來(lái)接受客戶端發(fā)送的數(shù)據(jù)
- 約束了服務(wù)器應(yīng)該以何種格式來(lái)反饋數(shù)據(jù)給瀏覽器
- 約束了瀏覽器應(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)碼
- 1xx : 表示普通消息,沒(méi)有特殊含義
- 2xx : 服務(wù)器響應(yīng)成功
- 200 成功 [重點(diǎn)掌握]
- 3xx : 表示重定向
- 301 永久重定向 [重點(diǎn)掌握]
- 302 臨時(shí)重定向
- 304 使用緩存(服務(wù)器沒(méi)有更新過(guò))
- 4xx : 表示請(qǐng)求失敗
- 403 權(quán)限不足,無(wú)法訪問(wèn)
- 404 資源找不到 [重點(diǎn)掌握]
- 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:
-
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:
- 值是數(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])
- prot 必需的 監(jiān)聽(tīng)的端口號(hào)
- host 可選的 監(jiān)聽(tīng)指定的地址(一般省略)
- backlog 可選, 參數(shù)是一個(gè)指定等待客戶端連接的最大數(shù)量, 默認(rèn)511( 一般不使用)
- 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ì)象常用的屬性
-
method 屬性,
值是一個(gè)字符串, 為客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí)使用的的方法, 常用的強(qiáng)求有"GET","POST","PUT","DETELE"
server.on("request", (req,res) => { console.log(req.method) // 打印請(qǐng)求方式 })
-
url 屬性
url 屬性值為客戶端發(fā)送請(qǐng)求時(shí)使用URL參數(shù)字符串
server.on("request", (req,res) => { console.log(req.url) })
我們可以根據(jù)用戶請(qǐng)求的路徑不同 相應(yīng)不同 的內(nèi)容
-
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ì)象常用的屬性
- writeHead : 設(shè)置有狀態(tài)碼的響應(yīng)頭信息
- setHeader: 設(shè)置單個(gè)響應(yīng)頭字段
- write: 發(fā)送響應(yīng)數(shù)據(jù)
- end : 結(jié)束響應(yīng)
2.3.2 可以利用writeHead方法來(lái)發(fā)送響應(yīng)頭
1. writeHead方法接受三個(gè)參數(shù)
- statusCode 第一個(gè)參數(shù), 必須傳遞, 執(zhí)行一個(gè)http 狀態(tài)碼 例如200
- reasonPhrase 第二個(gè)參數(shù)可選,就是對(duì)狀態(tài)碼的描述信息,是一個(gè)字符串,一般不使用
- 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)頭常用的字段
- content-type: 指定響應(yīng)內(nèi)容的的類型
- location : 用于將客戶端重定向到另外一個(gè)ur l地址
- set-cookie: 用于在客戶端創(chuàng)建cookie
- 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ù)
- name: 響應(yīng)頭的字段
- 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)