HTTP和應(yīng)用問(wèn)題
HTTP協(xié)議
應(yīng)用層協(xié)議,針對(duì)服務(wù)器端和客戶端的應(yīng)用之間的傳輸協(xié)議
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議
RFC2616,HTTP協(xié)議采用了請(qǐng)求/響應(yīng)模型
版本
HTTP/1.0
這是第一個(gè)在通訊中指定版本號(hào)的HTTP 協(xié)議版本,至今仍被廣泛采用,特別是在代理服務(wù)器中【一般用于郵箱代理服務(wù)器】
Nginx ("engine x") 是一個(gè)高性能的 HTTP 和 反向代理 服務(wù)器,也是一個(gè) IMAP/POP3/SMTP 服務(wù)器。內(nèi)存少,并發(fā)能力強(qiáng)
HTTP/1.1
當(dāng)前版本。默認(rèn)采用keep-alive模式,并能很好地配合代理服務(wù)器工作。還支持以管道方式同時(shí)發(fā)送多個(gè)請(qǐng)求,以便降低線路負(fù)載,提高傳輸速度。
HTTP/2
報(bào)文
Request請(qǐng)求

消息頭部:
- Accept 可接受的數(shù)據(jù)類型,MIME;
- Accept-Language
- Accept-Encoding
- User-Agent 發(fā)送端的系統(tǒng)信息【以Mozilla標(biāo)準(zhǔn):瀏覽器類型,OS類型,使用的平臺(tái)庫(kù)等】
- Referer 當(dāng)請(qǐng)求的uri不存在時(shí),轉(zhuǎn)至的上一個(gè)界面
- Host 請(qǐng)求端的域名
- Connection 連接方式,持久連接 keep-alive
-
Cookie
ae315a0e.png

get方式最多傳遞2038個(gè)字符;post將參數(shù)信息保存在request報(bào)文的請(qǐng)求體中
=》通過(guò)GET方法提交數(shù)據(jù),則數(shù)據(jù)存放在QUERY_STRING環(huán)境變量中,而POST方法提交的數(shù)據(jù)則可以從標(biāo)準(zhǔn)輸入流中獲取。
Response返回
狀態(tài)行
協(xié)議版本號(hào) 狀態(tài)碼 狀態(tài)code
消息報(bào)頭
Location 重定向接受到的Referer所指向的位置
Server 服務(wù)器端的信息
....
消息體
消息頭部:
- Content-Encoding
- Content-Language
- Content-Length 字節(jié)方式存儲(chǔ)
- Content-Type
-
date Last-Modified、Expires實(shí)體報(bào)頭域給出響應(yīng)過(guò)期的日期和時(shí)間
db56f2fe.png
HTTP狀態(tài)碼:
1xx:指示信息--表示請(qǐng)求已接收,繼續(xù)處理。
2xx:成功--表示請(qǐng)求已被成功接收、理解、接受。
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作。
4xx:客戶端錯(cuò)誤--請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)。
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求。
常見狀態(tài)代碼、狀態(tài)描述的說(shuō)明如下:
200 OK:客戶端請(qǐng)求成功。
300:Multiple Choices/多重選擇,表示被請(qǐng)求的文檔可以在多個(gè)地方找到
301:Moved Permanently,指所請(qǐng)求的文檔在別的地方,瀏覽器會(huì)自動(dòng)連接到新的URL
302:Found/找到,臨時(shí)交換地址而不是永久
303:See Other/參見其他信息
304:未修改;
400 Bad Request:客戶端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解。
401 Unauthorized:請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用。
403 Forbidden:服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)。
404 Not Found:請(qǐng)求資源不存在,舉個(gè)例子:輸入了錯(cuò)誤的URL。
500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤。
503 Server Unavailable:服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常。
tcp三次握手四次揮手協(xié)議

client首先發(fā)送連接請(qǐng)求,發(fā)送報(bào)文段,包括ack=0,syn=1,seq=x
server收到請(qǐng)求,為該TCP分配緩存及變量,發(fā)送報(bào)文段,包括ack=1,syn=1,ack=x+1,seq=y
client收到后確認(rèn),為該tcp分配緩存及變量,包括ack=1,syn=1,ack=y+1,seq=x+1
client發(fā)final報(bào)文,
server仍在傳輸,發(fā)ack報(bào)文;
待完成傳輸后,發(fā)final報(bào)文
client收到后發(fā)ack報(bào)文,server收到后才可以斷開連接
相應(yīng)狀態(tài):listen sys-send syn-revd established fin-wait close-wait time-wait last-ack close
=》socket連接建立
UDP和TCP的區(qū)別:
TCP,傳輸控制協(xié)議;面向連接的、可靠的字節(jié)流傳輸服務(wù)。bs交換數(shù)據(jù)前需三次握手協(xié)議建立連接;通過(guò)包的序號(hào)保證超時(shí)重發(fā)、重復(fù)包丟棄、順序傳輸;bs雙方需建立tcp緩存及變量空間,系統(tǒng)開銷大些。
UDP,用戶數(shù)據(jù)報(bào)協(xié)議;面向無(wú)連接的、非可靠的數(shù)據(jù)報(bào)協(xié)議。數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單、系統(tǒng)開銷小,傳輸速度快。=》可以在應(yīng)用層增加相關(guān)機(jī)制保證可靠與控制機(jī)制。
FTP、Telnet、SMTP(郵件傳輸協(xié)議,25)、HTTP、POP3(支持使用客戶端遠(yuǎn)程管理在服務(wù)器上的電子郵件,提供了SSL加密的POP3協(xié)議被稱為POP3S)等;
UDP是面向無(wú)連接的,使用這個(gè)協(xié)議的常見服務(wù)有DNS、SNMP(簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議)、QQ、流媒體協(xié)議等
現(xiàn)代瀏覽器:
現(xiàn)代瀏覽器的工作原理 - 文章 - 伯樂(lè)在線
從輸入U(xiǎn)RL到頁(yè)面下載完的過(guò)程中都發(fā)生了什么事情:
1、DNS的domain遞歸解析【首先瀏覽器緩存、在再OS緩存中找,沒有向localDNS服務(wù)器找,向根服務(wù)器找;根服務(wù)器返回區(qū)域的DNS服務(wù)器】
根據(jù)域名級(jí)別,一次從一級(jí)域名向二級(jí)、三級(jí)找。
2、tcp的三次握手【根據(jù)ip發(fā)起網(wǎng)絡(luò)連接,可能遇到重定向問(wèn)題,那重復(fù)1找到重定向之后的server】
3、browser的httprequest【包括資源路徑、身份驗(yàn)證】
4、server的httpresponse【client收到響應(yīng)內(nèi)容,頁(yè)面中的url,如圖像等資源再次請(qǐng)求;再進(jìn)行網(wǎng)頁(yè)渲染,包含css之后的html及圖片】
3、4主要和帶寬有關(guān)
解析html構(gòu)建dom樹->構(gòu)建render樹->布局render樹->繪制render樹。
加載速度的優(yōu)化:
瀏覽器內(nèi)核技術(shù):緩存、預(yù)取、壓縮、并行;
DNS級(jí)緩存預(yù)?。?、瀏覽器DNS緩存;2、系統(tǒng)DNS緩存;3、Hosts文件;4、各個(gè)DNS服務(wù)器上的緩存
HTTP和HTTPS的區(qū)
https安全性比http高,基于http+ssl,端口號(hào)默認(rèn)是443。主要是可進(jìn)行加密傳輸、身份認(rèn)證
1、身份認(rèn)證,需要server端有CA證書,證明服務(wù)器用途類型;
2、bs之間所有傳輸內(nèi)容都經(jīng)過(guò)加密; i. 具體講,是客戶端產(chǎn)生一個(gè)對(duì)稱的密鑰,通過(guò)server 的證書來(lái)交換密鑰. 一般意義上的握手過(guò)程. ii. 接下來(lái)所有的信息往來(lái)就都是加密的. 第三方即使截獲,也沒有任何意義.
SSL層
SSL,SSL運(yùn)行在TCP/IP層之上、應(yīng)用層之下,為應(yīng)用程序提供加密數(shù)據(jù)通道,它采用了RC4、MD5 以及RSA等加密算法,使用40 位的密鑰,適用于商業(yè)信息的加密。HTTPS和SSL支持使用X.509數(shù)字認(rèn)證。
具體交互
由于https 要還密鑰和確認(rèn)加密算法的需要,單握手就需要6/7 個(gè)往返。接下來(lái)才是具體的http協(xié)議,每一次響應(yīng)或者請(qǐng)求, 都要求客戶端和服務(wù)端對(duì)會(huì)話的內(nèi)容做加密/解密。=》所以對(duì)帶寬及cpu都有壓力
CA證書
需要CA認(rèn)證機(jī)構(gòu)頒發(fā),配合公網(wǎng)域名。
公網(wǎng)上要購(gòu)買證書,然后在nginx等負(fù)載均衡中間件配置私鑰文件。
域名
要在公網(wǎng)開放https的,需要購(gòu)買域名,域名和主體綁定。
前端安全性問(wèn)題
XSS,跨站腳本攻擊(Cross Site Script) 。它指的是惡意攻擊者往Web頁(yè)面里插入惡意html代碼,當(dāng)用戶瀏覽該頁(yè)之時(shí),嵌入的惡意html代碼會(huì)被執(zhí)行。如:彈出廣告
CSRF,跨站點(diǎn)偽造請(qǐng)求(Cross Site Request Forgery)。顧名思義就是 通過(guò)偽造連接請(qǐng)求在用戶不知情的情況下,讓用戶以自己的身份來(lái)完成攻擊者需要達(dá)到的一些目的。如:釣魚網(wǎng)站
cookie劫持,通過(guò)獲取頁(yè)面的權(quán)限,在頁(yè)面中寫一個(gè)簡(jiǎn)單的到惡意站點(diǎn)的請(qǐng)求,并攜帶用戶的cookie。 獲取cookie后通過(guò)cookie 就可以直以被盜用戶的身份登錄站點(diǎn)。這就是cookie 劫持。
項(xiàng)目升級(jí)為https:
由于https的網(wǎng)站內(nèi)嵌其它項(xiàng)目時(shí),要求內(nèi)嵌的項(xiàng)目也要https認(rèn)證的,否則瀏覽器安全限制打開不了。
ajax
Asynchronous JavaScript and XML,在服務(wù)器和客戶端之間充當(dāng)了一個(gè)緩沖器
原理
- 通過(guò)XmlHttpRequest對(duì)象來(lái)向服務(wù)器發(fā)異步請(qǐng)求,從服務(wù)器獲得數(shù)據(jù),然后用javascript來(lái)操作DOM而局部更新頁(yè)面
- 本身繼承了XMLHttpRequest 對(duì)象,所有現(xiàn)代瀏覽器均支持 XMLHttpRequest 對(duì)象(IE5 和 IE6 使用 ActiveXObject),用于在后臺(tái)與服務(wù)器交換數(shù)據(jù)
- 由下列技術(shù)組合而成:
- 使用CSS和XHTML來(lái)表示;
- 使用DOM模型來(lái)交互和動(dòng)態(tài)顯示;
- 使用XMLHttpRequest來(lái)和服務(wù)器進(jìn)行異步通信;
- 使用javascript來(lái)綁定和調(diào)用
$.ajax({
type:'GET', //默認(rèn)get
dataType:'json', //預(yù)期服務(wù)器返回的數(shù)據(jù)類型。如果不指定,jQuery 將自動(dòng)根據(jù) HTTP 包 MIME 信息來(lái)智能判斷
contentType:'application/x-www-form-urlencoded', //發(fā)送信息至服務(wù)器時(shí)內(nèi)容編碼類型
url:encodeURI(''), //特殊字符需要編碼
timeout:10000, //設(shè)置請(qǐng)求超時(shí)時(shí)間(毫秒)。此設(shè)置將覆蓋全局設(shè)置
data:{}, //post時(shí)傳遞數(shù)據(jù)
async: true, //默認(rèn)異步
cache: true,//默認(rèn)值: true,dataType 為 script 和 jsonp 時(shí)默認(rèn)為 false。設(shè)置為 false 將不緩存此頁(yè)面
sucess:function(data,textStatus){
},
error:function(XMLHttpRequset,textStatus,error){
}
});
-
好處:
- 頁(yè)面無(wú)刷新,異步方式不用打斷用戶的操作;
- 將一些服務(wù)器的工作轉(zhuǎn)嫁到客戶端;
- 基于標(biāo)準(zhǔn)化的并被廣泛支持的技術(shù),不需要小插件等
-
缺點(diǎn):
- ajax干掉了back按鈕,即對(duì)瀏覽器后退機(jī)制的破壞【google通過(guò)創(chuàng)建或使用一個(gè)隱藏的IFRAME來(lái)重現(xiàn)頁(yè)面上的變更】;
- ajax的邏輯處理對(duì)客戶端的安全掃描隱藏
Ajax不能重定向的問(wèn)題
-
問(wèn)題:發(fā)送一個(gè)接口請(qǐng)求,接口本身重定向到login界面;browser本身發(fā)送兩次請(qǐng)求,一個(gè)是接口的請(qǐng)求,response中是302狀態(tài),一個(gè)是重定向的請(qǐng)求,狀態(tài)是200,但不跳轉(zhuǎn)到login
9c2cab20.png

302 Found 是HTTP協(xié)議中的一個(gè)狀態(tài)碼(Status Code),可以簡(jiǎn)單的理解為該資源原本確實(shí)存在,但已經(jīng)被臨時(shí)改變了位置
原因:默認(rèn)ajax是不支持重定向,因?yàn)閍jax本身就是局部刷新,不重新加載頁(yè)面。導(dǎo)致雖然客戶端接受到了重定向,并發(fā)出了請(qǐng)求,狀態(tài)碼也是200,但是瀏覽器并沒有跳轉(zhuǎn)
解決:
- 前端根據(jù)json數(shù)據(jù)自己跳轉(zhuǎn)login
- 后端執(zhí)行重定向的動(dòng)作
java的重定向:
- 當(dāng)使用轉(zhuǎn)發(fā)forward時(shí),JSP容器將一個(gè)內(nèi)部的方法來(lái)調(diào)用目標(biāo)頁(yè)面,新的頁(yè)面繼續(xù)處理同一個(gè)請(qǐng)求,而瀏覽器將不會(huì)知道這個(gè)過(guò)程;直接經(jīng)由server完成不同url訪問(wèn)
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
try {
rd.forward(request, response);
return; //如果不加,會(huì)報(bào)Cannot forward after response has been committed
}catch(Exception e){
}
- 重定向方式的含義是第一個(gè)頁(yè)面通知瀏覽器發(fā)送一個(gè)新的頁(yè)面請(qǐng)求
httpServletResponse.sendRedirect(url);
sendRedirect轉(zhuǎn)發(fā)更快,而且能保持request內(nèi)的對(duì)象=》可以解決頁(yè)面session傳遞問(wèn)題;兩者在調(diào)用它們之前,都不能有內(nèi)容已經(jīng)被實(shí)際輸出到了客戶端。如果緩沖區(qū)中已經(jīng)有了一些內(nèi)容,這些內(nèi)容將被從緩沖區(qū)中清除
跨域
同源策略的限制。一般為了安全型,要求在域域名、端口號(hào)、協(xié)議上是一致的
不會(huì)判斷是否是同一個(gè)ip
但限制了注入iframe和ajax的應(yīng)用,需要跨域訪問(wèn)
- js跨域訪問(wèn)方式:
使用document.domian來(lái)跨域
jsonp
JSON with Padding,動(dòng)態(tài)創(chuàng)建script;同源策略不禁止在頁(yè)面中引用其他域的JS文件,并可以自由執(zhí)行引入的JS文件中的function(包括操作cookie、Dom等等)
- 示例:
function jsonpCallback(result) {
//alert(result);
for(var i in result) {
alert(i+":"+result[i]);//循環(huán)輸出a:1,b:2,etc.
}
}
var JSONP=document.createElement("script");
JSONP.type="text/javascript";
JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback"; //客戶端注冊(cè)一個(gè)jsonp,將callback名字傳遞給服務(wù)器
document.getElementsByTagName("head")[0].appendChild(JSONP); //將該源像web中元素引入
//服務(wù)器端以js語(yǔ)法創(chuàng)建callback函數(shù)
- 缺點(diǎn):1、需要前后端協(xié)作;2、url使用相對(duì)路徑;3、jsonp是get形式,承載的信息量有限
使用window.name進(jìn)行跨域數(shù)據(jù)傳輸
CORS
Cross-origin resource sharing 定義一種跨域訪問(wèn)的機(jī)制,可以讓AJAX實(shí)現(xiàn)跨域訪問(wèn)
實(shí)現(xiàn)此功能非常簡(jiǎn)單,只需由服務(wù)器發(fā)送一個(gè)響應(yīng)標(biāo)頭即可;但需要特定瀏覽器支持
1ccbc2ad.png
支持的瀏覽器:

后臺(tái)設(shè)置:
1、
((HttpServletResponse) response).setHeader("Access-Control-Allow-Origin","*"); //cy:調(diào)試階段,后期去掉
((HttpServletResponse) response).setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); //解決application/x-www-form-urlencoded, multipart/form-data, or text/plain跨域問(wèn)題
//或者指定域名
response.setHeader("Access-Control-Allow-Origin","name");
2、Spring MVC 4.2.5以后新增的支持跨域的注解@CrossOrigin
- 限制:
- 只能使用ajax請(qǐng)求,而不是form中action
-
Access-Control-Allow-Origin: *允許任何來(lái)自任意域的跨域請(qǐng)求,那么久存在被 DDoS攻擊的可能
超時(shí)重試
如果應(yīng)用不設(shè)置超時(shí),則可能會(huì)導(dǎo)致請(qǐng)求響應(yīng)慢,慢請(qǐng)求累積導(dǎo)致連鎖反應(yīng);
重試次數(shù)太多會(huì)導(dǎo)致多倍請(qǐng)求流量,即模擬了DDoS攻擊;讀服務(wù)天然適合重試,但寫服務(wù)大多不能重試
在進(jìn)行代碼Review時(shí),一定記得Review超時(shí)與重試機(jī)制
可能出現(xiàn)的超時(shí)節(jié)點(diǎn):
- 代理層超時(shí)與重試:如Haproxy、Nginx、Twemproxy,這些組件實(shí)現(xiàn)代理功能,如Haproxy和Nginx可以實(shí)現(xiàn)請(qǐng)求的負(fù)載均衡
- Web容器超時(shí):如Tomcat、Jetty等,提供HTTP服務(wù)運(yùn)行環(huán)境的
- 中間件客戶端超時(shí)與重試:如JSF(京東SOA框架)、Dubbo、JMQ(京東消息中間件)
- 數(shù)據(jù)庫(kù)客戶端超時(shí):如Mysql、Oracle,需要分別設(shè)置JDBC Connection、Statement的網(wǎng)絡(luò)連接/讀/寫超時(shí)時(shí)間。事務(wù)超時(shí)時(shí)間,獲取連接池連接等待時(shí)間
- 前端Ajax超時(shí):瀏覽器通過(guò)Ajax訪問(wèn)時(shí)的網(wǎng)絡(luò)連接/讀/寫超時(shí)時(shí)間
問(wèn)題:
新平臺(tái)(端口彼此獨(dú)立,不共享session),后端接收到兩次請(qǐng)求,第1次是有session情況,第2次是訪問(wèn)另外的端口跳轉(zhuǎn)到login界面(確定是filter中轉(zhuǎn)的)解決:
- 反向代理Nginx的配置
增加配置:
proxy_next_upstream http_502 http_504 error timeout invalid_header; #表示對(duì)error和timeout的進(jìn)行重試到下一個(gè)節(jié)點(diǎn)
proxy_read_timeout 60s; #連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí)時(shí)間)
proxy_send_timeout 60; #后端服務(wù)器數(shù)據(jù)回傳時(shí)間(代理發(fā)送超時(shí)時(shí)間)
proxy_connect_timeout:75; #nginx連接后端的超時(shí)時(shí)間,一般不超過(guò)75s
- weblogic超時(shí)設(shè)置
一、web.xml
設(shè)置WEB應(yīng)用程序描述符web.xml里的<session-timeout>元素。這個(gè)值以分鐘為單位,并覆蓋weblogic.xml中的TimeoutSecs屬性,此例表示Session將在54分鐘后過(guò)期。
<session-config>
<session-timeout>54</session-timeout>
</session-config>
當(dāng)<session-timeout>設(shè)置為-2,表示將使用在weblogic.xml中設(shè)置的TimeoutSecs這個(gè)屬性值。
當(dāng)<session-timeout>設(shè)置為-1,表示Session將永不過(guò)期,而忽略在weblogic.xml中設(shè)置的TimeoutSecs屬性值。該屬性值可以通過(guò)console控制臺(tái)來(lái)設(shè)置
二、weblogic.xml
設(shè)置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的TimeoutSecs屬性。這個(gè)值以秒為單位。該文件放在項(xiàng)目的web-inf下。
<session-descriptor>
<session-param>
<param-name>TimeoutSecs</param-name>
<param-value>3600</param-value>
</session-param>
</session-descriptor>
默認(rèn)值是3600秒
客戶端超時(shí)設(shè)置
Connection: keep-alive每次http請(qǐng)求都要?jiǎng)?chuàng)建一個(gè)連接,而創(chuàng)建連接的過(guò)程需要消耗資源和時(shí)間,為了減少資源消耗,縮短響應(yīng)時(shí)間,就需要重用連接;Keep-Alive: timeout=time,即告知客戶端長(zhǎng)連接超時(shí)時(shí)間
http/1.0默認(rèn)是關(guān)閉長(zhǎng)連接的,需要添加HTTP請(qǐng)求頭“Connection:Keep-Alive”才能啟用。而http/1.1默認(rèn)啟用長(zhǎng)連接,需要添加HTTP請(qǐng)求頭“Connection: close”才關(guān)閉ajax超時(shí)設(shè)置
Ajax 請(qǐng)求是限時(shí)的,所以錯(cuò)誤警告被捕獲并處理后,可以用來(lái)提升用戶體驗(yàn)。請(qǐng)求超時(shí)這個(gè)參數(shù)通常就保留其默認(rèn)值,要不就通過(guò) jQuery.ajaxSetup 來(lái)全局設(shè)定,很少為特定的請(qǐng)求重新設(shè)置 timeout 選項(xiàng)



