GET請求與POST請求
前言
HTTP請求,最初設(shè)定了八種方法(也稱為“動(dòng)作”)巷怜。這八種方法本質(zhì)上沒有任何區(qū)別葛超。只是讓請求,更加有語義而已延塑。
八種方法分別為:OPTIONS绣张、HEAD、GET关带、POST侥涵、PUT、DELETE豫缨、TRACE独令、CONNECT
這八種方法最終經(jīng)過“歲月沉淀”后,常用的只有兩種好芭,即:GET和POST
GET
1. 含義:從指定的資源獲取數(shù)據(jù)(一種“索取”的感覺)燃箭。
2. 什么時(shí)候使用GET請求較為合適?
(1)單純獲取數(shù)據(jù)的時(shí)舍败。
(2)請求中不包含敏感數(shù)據(jù)時(shí)招狸。
POST
1.含義:向指定的資源提交要被處理的數(shù)據(jù)(一種“交差”的感覺)敬拓。
2.什么時(shí)候使用POST請求較為合適?
(1)傳送相對敏感數(shù)據(jù)時(shí)裙戏。
(2)請求的結(jié)果有持續(xù)性的副作用乘凸,例如:傳遞的數(shù)據(jù)要作為數(shù)據(jù)源寫入數(shù)據(jù)庫時(shí)。
備注:使用了POST不代表的絕對的安全累榜。
常見的GET請求:
1.瀏覽器地址欄輸入網(wǎng)址時(shí)(瀏覽器請求網(wǎng)頁時(shí)時(shí)GET請求营勤,且不可更改)
2.可以請求外部資源的html標(biāo)簽,例如:<img> <a> <link> <script>
3.發(fā)送Ajax時(shí)明確指出了使用GET請求
4.form表單提交時(shí)沒有指明方式壹罚,默認(rèn)使用GET
常見的POST請求:
1.發(fā)送Ajax時(shí)明確指出了使用POST方式
2.使用第三方發(fā)送Ajax請求庫時(shí)明確指出用POST時(shí)
3.form表單提交時(shí)明確指出使用POST方式
二者的區(qū)別
express服務(wù)器
//1.引入express
let express = require('express')
//2.創(chuàng)建app服務(wù)對象
let app = express()
//隱藏服務(wù)器的具體實(shí)現(xiàn)
app.disable('x-powered-by')
//3.設(shè)置路由(這里配置的是后端路由) 路由可以理解為:key-value的組合葛作,響應(yīng)路由是一個(gè)匹配的過程。
//根路由
app.get('/',(request,response)=>{
response.send('<h2>我是主界面</h2>')
})
//一級路由
app.get('/meishi',(request,response)=>{
/*
什么樣的請求能交給這個(gè)回調(diào)函數(shù)處理猖凛?
1.發(fā)送的請求必須為GET請求
2.訪問的URL中關(guān)鍵詞是meishi
備注:使用request.query只能獲取查詢字符串參數(shù)
*/
console.log(request.query);
response.send('<h2>我是美食界面</h2>')
})
//二級路由
app.get('/meishi/huoguo',(request,response)=>{
/*
什么樣的請求能交給這個(gè)回調(diào)函數(shù)處理赂蠢?
1.發(fā)送的請求必須為GET請求
2.訪問的URL中關(guān)鍵詞是meishi
*/
response.send('<h2>我是美食---火鍋界面</h2>')
})
app.post('/demo',(request,response)=>{
/*
* 備注:使用request.body能夠獲取POST請求過來的請求體中的參數(shù),但是需要借助一個(gè)中間件辨泳。
* */
console.log(request.body);
response.send('你發(fā)來的post請求虱岂,我收到了,這是我給你的響應(yīng)')
})
app.get('/demo',(request,response)=>{
response.send('你發(fā)來的get請求菠红,我收到了第岖,這是我給你的響應(yīng)')
})
//4.綁定端口監(jiān)聽
app.listen(3000,(err)=>{
if (!err) console.log('服務(wù)器啟動(dòng)成功了!')
else console.log(err)
})
http協(xié)議
- http協(xié)議是什么:超文本傳輸協(xié)議(屬于應(yīng)用層協(xié)議)
- 特點(diǎn):無狀態(tài)途乃,現(xiàn)在cookie解決了無狀態(tài)的問題(早期網(wǎng)頁開發(fā)時(shí)绍傲,用cookie解決,現(xiàn)在是cookie和session配合使用)
- 作用:規(guī)定了服務(wù)器和客戶端傳遞信息的規(guī)則(統(tǒng)稱為報(bào)文耍共,分為:請求報(bào)文烫饼、響應(yīng)報(bào)文。)
- 版本:
- http 1.0 (老版本) ---------- 不支持長連接
- http 1.1 (主流版本)--------- 優(yōu)點(diǎn):支持長連接试读,弊端:同時(shí)發(fā)送資源的數(shù)量過小杠纵。
- http 2.0 (最新版) ---------- 同時(shí)發(fā)送資源的數(shù)量稍有提升。
- 報(bào)文(請求報(bào)文钩骇、響應(yīng)報(bào)文)的組成:
1.報(bào)文首行
2.報(bào)文頭
3.空行(僅僅作為一個(gè)分割)
4.報(bào)文體
http報(bào)文與http狀態(tài)碼
1.分析GET請求報(bào)文(給服務(wù)器看的)
GET http://localhost:3000/meishi HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
DNT: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
空行
空行
報(bào)文首行
GET http://localhost:3000/meishi HTTP/1.1
-請求類型 協(xié)議名://主機(jī)名:端口號/路由關(guān)鍵詞 使用協(xié)議的版本
報(bào)文頭
Host: localhost:3000
--訪問的主機(jī)名(地址比藻,僅僅包含主機(jī)名+端口號)
--防盜鏈、廣告計(jì)費(fèi)
Connection: keep-alive
--告訴服務(wù)器倘屹,瀏覽器端支持長連接
Upgrade-Insecure-Requests: 1
--告訴服務(wù)器银亲,瀏覽器端支持https協(xié)議
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
--用戶代理,告知服務(wù)器你的瀏覽器內(nèi)核以及品牌纽匙,早期的時(shí)候用于判斷用戶的瀏覽器是哪一個(gè)品牌务蝠,現(xiàn)在不可用了。
DNT: 1
--禁止跟蹤烛缔,告知服務(wù)器禁止跟蹤馏段,并不是寫了該字段服務(wù)器就一定遵守轩拨。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
--告知服務(wù)器瀏覽器能接受的文件類型,q是資源的優(yōu)先級院喜,取值范圍是0-1,1的權(quán)限最高亡蓉,默認(rèn)是1
Accept-Encoding: gzip, deflate, br
--告訴服務(wù)器瀏覽器能支持的文件壓縮格式
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
--告訴服務(wù)器,瀏覽器能夠接受的語言
空行
報(bào)文體
GET 請求沒有報(bào)文體
2.分析POST請求報(bào)文(給服務(wù)器看的)
POST http://localhost:3000/demo HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 16
Cache-Control: max-age=0
Origin: http://localhost:63342
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng, */ *;q=0.8,application/signed-exchange;v=b3
Referer: http://localhost:63342/node/day04/1.express%E6%9C%8D%E5%8A%A1%E5%99%A8/demo.html?_ijt=tjfnb0cpos62ql8umjmm9v24ve
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Webstorm-9af2238=09820128-3adb-43e4-8242-a6f65c9e523a
name=kobe&age=18
報(bào)文首行
POST http://localhost:3000/demo HTTP/1.1
-
報(bào)文頭
Host: localhost:3000
--訪問的主機(jī)名(地址喷舀,僅僅包含主機(jī)名+端口號)
Connection: keep-alive
--告訴服務(wù)器砍濒,瀏覽器端支持長連接
Content-Length: 16
--請求體的長度
Cache-Control: max-age=0
--用于控制強(qiáng)緩存
Origin: http://localhost:63342
--當(dāng)前所處位置(主機(jī)位置+端口位置)
Upgrade-Insecure-Requests: 1
--告訴服務(wù)器,瀏覽器端支持https協(xié)議
DNT: 1
--禁止跟蹤硫麻,告知服務(wù)器禁止跟蹤梯影,并不是寫了該字段服務(wù)器就一定遵守。
Content-Type: application/x-www-form-urlencoded
--標(biāo)識該請求是來自于一個(gè)form表單庶香,并且以urlencoded形式進(jìn)行編碼
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
--用戶代理,告知服務(wù)器你的瀏覽器內(nèi)核以及品牌简识,早期的時(shí)候用于判斷用戶的瀏覽器是拿一個(gè)品牌赶掖,現(xiàn)在不可用了。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,* / *;q=0.8,application/signed-exchange;v=b3
--告知服務(wù)器瀏覽器能接受的文件類型七扰,q是資源的優(yōu)先級奢赂,取值范圍是0-1,1的權(quán)限最高,默認(rèn)是1
Referer: http://localhost:63342/node/day04/1.express%E6%9C%8D%E5%8A%A1%E5%99%A8/demo.html?_ijt=tjfnb0cpos62ql8umjmm9v24ve
--在當(dāng)前url下發(fā)出去的請求颈走,是一個(gè)完整url膳灶,也可以做防盜鏈、同時(shí)也可以做廣告計(jì)費(fèi)
Accept-Encoding: gzip, deflate, br
--告訴服務(wù)器瀏覽器能支持的文件壓縮格式
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
--告訴服務(wù)器立由,瀏覽器能夠接受的語言
Cookie: Webstorm-9af2238=09820128-3adb-43e4-8242-a6f65c9e523a
--Webstorm幫你“種”的一個(gè)cookie
空行
報(bào)文體
name=kobe&age=18
--攜帶過去的數(shù)據(jù)轧钓,以urlencoded進(jìn)行編碼
3.分析響應(yīng)報(bào)文(給瀏覽器看的)
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 27
ETag: W/"1b-q8c2w67PUz7P4t0CNbDw9xqw6bo"
Date: Tue, 23 Jul 2019 06:20:18 GMT
Connection: keep-alive
<h2>我是美食界面</h2>
報(bào)文首行
HTTP/1.1 200 OK
協(xié)議名/協(xié)議版本 狀態(tài)碼
報(bào)文頭
X-Powered-By: Express
-服務(wù)器所使用的框架
Content-Type: text/html; charset=utf-8
-告訴瀏覽器解析文件的方式;文件編碼方式
Content-Length: 27
-響應(yīng)體的長度
ETag: W/"1b-NFYx6TA4AihYceTsWYDlBLJferg"
-協(xié)商緩存(資源唯一標(biāo)識)
Date: Tue, 23 Jul 2019 06:20:18 GMT
-日期
Connection: keep-alive
-告訴瀏覽器锐膜,服務(wù)器支持長連接
空行
報(bào)文體
<h2>我是美食界面</h2>
4.http狀態(tài)碼(服務(wù)器給客戶端的東西)
作用:
- 告訴客戶端毕箍,當(dāng)前服務(wù)器處理請求的結(jié)果
http狀態(tài)碼的分類
- 1xx : 服務(wù)器已經(jīng)收到了本次請求,但是還需要進(jìn)一步的處理才可以道盏。
- 2xx : 服務(wù)器已經(jīng)收到了本次請求而柑,且已經(jīng)分析、處理等........最終處理完畢荷逞!
- 3xx : 服務(wù)器已經(jīng)接收到了請求媒咳,還需要其他的資源,或者重定向到其他位置种远,甚至交給其他服務(wù)器處理涩澡。
- 4xx :一般指請求的參數(shù)或者地址有錯(cuò)誤, 出現(xiàn)了服務(wù)器無法理解的請求(一般是前端的鍋)院促。
- 5xx :服務(wù)器內(nèi)部錯(cuò)誤(不是因?yàn)檎埱蟮刂坊蛘哒埱髤?shù)不當(dāng)造成的)筏养,無法響應(yīng)用戶請求(一般是后端人員的鍋)斧抱。
常見的幾個(gè)狀態(tài)碼
- 200 :成功(最理想狀態(tài))
- 301 :重定向,被請求的舊資源永久移除了(不可以訪問了)渐溶,將會跳轉(zhuǎn)到一個(gè)新資源辉浦,搜索引擎在抓取新內(nèi)容的同時(shí)也將舊的網(wǎng)址替換為重定向之后的網(wǎng)址;
- 302 :重定向茎辐,被請求的舊資源還在(仍然可以訪問)宪郊,但會臨時(shí)跳轉(zhuǎn)到一個(gè)新資源,搜索引擎會抓取新的內(nèi)容而保存舊的網(wǎng)址拖陆。
- 304 :請求資源重定向到緩存中(命中了協(xié)商緩存)弛槐。
- 404 :資源未找到,一般是客戶端請求了不存在的資源依啰。
- 500 :服務(wù)器收到了請求乎串,但是服務(wù)器內(nèi)部產(chǎn)生了錯(cuò)誤。
- 502 :連接服務(wù)器失斔倬(服務(wù)器在處理一個(gè)請求的時(shí)候叹誉,或許需要其他的服務(wù)器配合,但是聯(lián)系不上其他的服務(wù)器了)闷旧。
經(jīng)典面試題
問題:從用戶輸入U(xiǎn)Rl按下回車长豁,一直到用戶能看到界面,期間經(jīng)歷了什么忙灼?
一匠襟、DNS解析(緩存):
1.找瀏覽器DNS緩存解析域名
2.找本機(jī)DNS緩存:ipconfig/displaydns > C:/dns.txt
3.找路由器DNS緩存
4.找運(yùn)營商DNS緩存(百分之80的DNS查找,到這一步就結(jié)束)
5.遞歸查詢该园,(最不愿意看到的事酸舍,查詢的是全球13臺DNS根服務(wù)器中的一個(gè))
二、進(jìn)行TCP(協(xié)議)連接爬范,三次握手(根據(jù)上一步請求回來的ip地址父腕,去聯(lián)系服務(wù)器)
第一次握手:由瀏覽器發(fā)給服務(wù)器,我想和你說話青瀑,你能“聽見”嘛璧亮?
第二次握手:由服務(wù)器發(fā)給瀏覽器,我能聽得見斥难,你說吧枝嘶!
第三次握手:由瀏覽器發(fā)給服務(wù)器,好哑诊,那我就開始說話群扶。
三、發(fā)送請求(請求報(bào)文)
四、得到響應(yīng)(響應(yīng)報(bào)文)
五竞阐、瀏覽器開始解析html
--預(yù)解析:將所有外部的資源缴饭,發(fā)請求出去
--解析html,生成DOM樹
--解析CSS骆莹,生成CSSOM樹
--合并成一個(gè)render樹
--js是否操作了DOM或樣式
--有:進(jìn)行重繪重排(不好颗搂,1.盡量避免;2.最小化重繪重排)
--沒有:null
--最終展示界面
六幕垦、斷開TCP連接丢氢,四次揮手(確保數(shù)據(jù)的完整性)
第一次揮手:由瀏覽器發(fā)給服務(wù)器,我的東西接受完了先改,你關(guān)閉吧疚察。
第二次揮手:由服務(wù)器發(fā)給瀏覽器,我還有一些東西沒接收完仇奶,你等一會貌嫡,我接收好了我告訴你
第三次揮手:由服務(wù)器發(fā)給瀏覽器,我接收完了该溯,你斷開吧
第四次揮手:由瀏覽器發(fā)給服務(wù)器衅枫,好的,那我斷開了朗伶。
路由的使用
//1.引入express
let express = require('express')
//2.創(chuàng)建app服務(wù)對象
let app = express()
//3.設(shè)置路由
//根路由
app.get('/',(request,response)=>{
/*
* request:
* request.query 獲取查詢字符串的參數(shù),拿到的是一個(gè)對象
* request.params 獲取參數(shù)路由的參數(shù)步咪,拿到的是一個(gè)對象
* request.body 獲取post請求體论皆,拿到的是一個(gè)對象(要借助一個(gè)中間件)
* request.get(xxxx) 獲取請求頭中指定key對應(yīng)的value
*
* response:
* response.send() 給瀏覽器做出一個(gè)響應(yīng)
response.end() 給瀏覽器做出一個(gè)響應(yīng)(不會自動(dòng)追加響應(yīng)頭,容易亂碼)
response.download() 告訴瀏覽器下載一個(gè)文件(相對路徑)
response.sendFile() 給瀏覽器發(fā)送一個(gè)文件(絕對路徑)
response.redirect() 重定向到一個(gè)新的地址(url)
response.set(header,value) 自定義響應(yīng)頭內(nèi)容
response.get() 獲取響應(yīng)頭指定key對應(yīng)的value
res.status(code) 設(shè)置響應(yīng)狀態(tài)碼
* */
//console.log(request.query);
//console.log(request.get('host'))
response.set('demo',123)
console.log(response.get('demo'));
response.send('ok')
//response.download('./public/隊(duì)列.jpg')
//response.sendFile(__dirname+'/public/demo.html')
//response.sendFile(__dirname+'/public/demo.zip')
//response.redirect('https://www.baidu.com')
})
//一級路由
app.get('/meishi',(request,response)=>{
console.log(request.params);
response.send('我是美食路由的反饋')
})
//二級路由
app.get('/meishi/huoguo',(request,response)=>{
console.log(request.params);
response.send('我是美食--火鍋路由的反饋')
})
//參數(shù)路由
app.get('/meishi/:id',(request,response)=>{
console.log(request.params);
response.send('我是參數(shù)路由的反饋')
})
//4.綁定端口監(jiān)聽
app.listen(3000,(err)=>{
if (!err) console.log('服務(wù)器啟動(dòng)成功了')
else console.log(err)
})
中間件
/*
中間件:
概念:本質(zhì)上就是一個(gè)函數(shù)猾漫,包含三個(gè)參數(shù):request点晴、response、next
作用:
1) 執(zhí)行任何代碼悯周。
2) 修改請求和響應(yīng)對象粒督。
3) 終結(jié)請求-響應(yīng)循環(huán)。
4) 調(diào)用堆棧中的下一個(gè)中間件或路由禽翼。
分類:
1) 應(yīng)用(全局)級中間件(過濾非法的請求屠橄,例如防盜鏈)
--第一種寫法:app.use((request,response,next)=>{}
--第二種寫法:使用函數(shù)定義
2) 第三方中間件(通過npm下載的中間件,例如body-parser)
--app.use(bodyParser.urlencoded({extended:true}))
3) 內(nèi)置中間件(express內(nèi)部封裝好的中間件)
--app.use(express.urlencoded({extended:true}))
--app.use(express.static('public'))
4) 路由器中間件 (Router)
--后面會說
備注:
1.在express中闰挡,定義路由和中間件的時(shí)候锐墙,根據(jù)定義的順序(代碼的順序),將定義的每一個(gè)中間件或路由长酗,
放在一個(gè)類似于數(shù)組的容器中溪北,當(dāng)請求過來的時(shí)候,依次從容器中取出中間件和路由,進(jìn)行匹配之拨,如果匹配
成功茉继,交由該路由或中間件處理。
2.對于服務(wù)器來說蚀乔,一次請求烁竭,只有一個(gè)請求對象,和一個(gè)響應(yīng)對象乙墙,其他任何的request和response都是對二者的引用颖变。
*/
let express = require('express')
let bodyParser = require('body-parser')
let app = express()
//使用body-parser中間件解析post請求過來的請求體參數(shù)為一個(gè)對象,隨后掛載到request上
//app.use(bodyParser.urlencoded({extended:true}))
//內(nèi)置中間件 ---- 解析post請求過來的請求體參數(shù)為一個(gè)對象听想,隨后掛載到request上
app.use(express.urlencoded({extended:true}))
//內(nèi)置中間件 ---- 暴露靜態(tài)資源
app.use(express.static('public'))
//全局中間件的第一種寫法
/*app.use(function (request,response,next) {
if(request.get('host') !== 'localhost:3000'){
response.send('禁止發(fā)送非法請求')
}else{
next() //讓下一個(gè)匹配的路由或中間件生效
}
})*/
//全局中間件的第二種寫法
function myMiddleWare(request,response,next) {
if(request.get('host') !== 'localhost:3000'){
response.send('禁止發(fā)送非法請求')
}else{
request.demo = 123
next() //讓下一個(gè)匹配的路由或中間件生效
}
}
app.get('/',myMiddleWare,(request,response)=>{
console.log(request.demo);
response.send('我是根路由的響應(yīng)')
})
app.get('/meishi',(request,response)=>{
response.send('我是美食路由的響應(yīng)')
})
app.post('/demo',(request,response)=>{
console.log(request.body)
response.send('post請求得到回應(yīng)了')
})
/*app.get('/index',(request,response)=>{
response.sendFile(__dirname+'/public/index.html')
})*/
app.listen(3000,(err)=>{
if(!err)console.log('ok')
else console.log(err)
})