HTTP和應用問題
HTTP協(xié)議
應用層協(xié)議,針對服務器端和客戶端的應用之間的傳輸協(xié)議
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協(xié)議
RFC2616,HTTP協(xié)議采用了請求/響應模型
版本
HTTP/1.0
這是第一個在通訊中指定版本號的HTTP 協(xié)議版本,至今仍被廣泛采用,特別是在代理服務器中【一般用于郵箱代理服務器】
Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 服務器。內(nèi)存少,并發(fā)能力強
HTTP/1.1
當前版本。默認采用keep-alive模式,并能很好地配合代理服務器工作。還支持以管道方式同時發(fā)送多個請求,以便降低線路負載,提高傳輸速度。
HTTP/2
報文
Request請求
消息頭部:
- Accept 可接受的數(shù)據(jù)類型,MIME;
- Accept-Language
- Accept-Encoding
- User-Agent 發(fā)送端的系統(tǒng)信息【以Mozilla標準:瀏覽器類型,OS類型,使用的平臺庫等】
- Referer 當請求的uri不存在時,轉(zhuǎn)至的上一個界面
- Host 請求端的域名
- Connection 連接方式,持久連接 keep-alive
-
Cookie
ae315a0e.png
get方式最多傳遞2038個字符;post將參數(shù)信息保存在request報文的請求體中
=》通過GET方法提交數(shù)據(jù),則數(shù)據(jù)存放在QUERY_STRING環(huán)境變量中,而POST方法提交的數(shù)據(jù)則可以從標準輸入流中獲取。
Response返回
狀態(tài)行
協(xié)議版本號 狀態(tài)碼 狀態(tài)code
消息報頭
Location 重定向接受到的Referer所指向的位置
Server 服務器端的信息
....
消息體
消息頭部:
- Content-Encoding
- Content-Language
- Content-Length 字節(jié)方式存儲
- Content-Type
-
date Last-Modified、Expires實體報頭域給出響應過期的日期和時間
db56f2fe.png
HTTP狀態(tài)碼:
1xx:指示信息--表示請求已接收,繼續(xù)處理。
2xx:成功--表示請求已被成功接收、理解、接受。
3xx:重定向--要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現(xiàn)。
5xx:服務器端錯誤--服務器未能實現(xiàn)合法的請求。
常見狀態(tài)代碼、狀態(tài)描述的說明如下:
200 OK:客戶端請求成功。
300:Multiple Choices/多重選擇,表示被請求的文檔可以在多個地方找到
301:Moved Permanently,指所請求的文檔在別的地方,瀏覽器會自動連接到新的URL
302:Found/找到,臨時交換地址而不是永久
303:See Other/參見其他信息
304:未修改;
400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。
401 Unauthorized:請求未經(jīng)授權,這個狀態(tài)代碼必須和WWW-Authenticate報頭域一起使用。
403 Forbidden:服務器收到請求,但是拒絕提供服務。
404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
500 Internal Server Error:服務器發(fā)生不可預期的錯誤。
503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間后可能恢復正常。
tcp三次握手四次揮手協(xié)議
client首先發(fā)送連接請求,發(fā)送報文段,包括ack=0,syn=1,seq=x
server收到請求,為該TCP分配緩存及變量,發(fā)送報文段,包括ack=1,syn=1,ack=x+1,seq=y
client收到后確認,為該tcp分配緩存及變量,包括ack=1,syn=1,ack=y+1,seq=x+1
client發(fā)final報文,
server仍在傳輸,發(fā)ack報文;
待完成傳輸后,發(fā)final報文
client收到后發(fā)ack報文,server收到后才可以斷開連接
相應狀態(tài):listen sys-send syn-revd established fin-wait close-wait time-wait last-ack close
=》socket連接建立
UDP和TCP的區(qū)別:
TCP,傳輸控制協(xié)議;面向連接的、可靠的字節(jié)流傳輸服務。bs交換數(shù)據(jù)前需三次握手協(xié)議建立連接;通過包的序號保證超時重發(fā)、重復包丟棄、順序傳輸;bs雙方需建立tcp緩存及變量空間,系統(tǒng)開銷大些。
UDP,用戶數(shù)據(jù)報協(xié)議;面向無連接的、非可靠的數(shù)據(jù)報協(xié)議。數(shù)據(jù)結(jié)構簡單、系統(tǒng)開銷小,傳輸速度快。=》可以在應用層增加相關機制保證可靠與控制機制。
FTP、Telnet、SMTP(郵件傳輸協(xié)議,25)、HTTP、POP3(支持使用客戶端遠程管理在服務器上的電子郵件,提供了SSL加密的POP3協(xié)議被稱為POP3S)等;
UDP是面向無連接的,使用這個協(xié)議的常見服務有DNS、SNMP(簡單網(wǎng)絡管理協(xié)議)、QQ、流媒體協(xié)議等
現(xiàn)代瀏覽器:
從輸入URL到頁面下載完的過程中都發(fā)生了什么事情:
1、DNS的domain遞歸解析【首先瀏覽器緩存、在再OS緩存中找,沒有向localDNS服務器找,向根服務器找;根服務器返回區(qū)域的DNS服務器】
根據(jù)域名級別,一次從一級域名向二級、三級找。
2、tcp的三次握手【根據(jù)ip發(fā)起網(wǎng)絡連接,可能遇到重定向問題,那重復1找到重定向之后的server】
3、browser的httprequest【包括資源路徑、身份驗證】
4、server的httpresponse【client收到響應內(nèi)容,頁面中的url,如圖像等資源再次請求;再進行網(wǎng)頁渲染,包含css之后的html及圖片】
3、4主要和帶寬有關
解析html構建dom樹->構建render樹->布局render樹->繪制render樹。
加載速度的優(yōu)化:
瀏覽器內(nèi)核技術:緩存、預取、壓縮、并行;
DNS級緩存預取:1、瀏覽器DNS緩存;2、系統(tǒng)DNS緩存;3、Hosts文件;4、各個DNS服務器上的緩存
HTTP和HTTPS的區(qū)
https安全性比http高,基于http+ssl,端口號默認是443。主要是可進行加密傳輸、身份認證
1、身份認證,需要server端有CA證書,證明服務器用途類型;
2、bs之間所有傳輸內(nèi)容都經(jīng)過加密; i. 具體講,是客戶端產(chǎn)生一個對稱的密鑰,通過server 的證書來交換密鑰. 一般意義上的握手過程. ii. 接下來所有的信息往來就都是加密的. 第三方即使截獲,也沒有任何意義.
SSL層
SSL,SSL運行在TCP/IP層之上、應用層之下,為應用程序提供加密數(shù)據(jù)通道,它采用了RC4、MD5 以及RSA等加密算法,使用40 位的密鑰,適用于商業(yè)信息的加密。HTTPS和SSL支持使用X.509數(shù)字認證。
具體交互
由于https 要還密鑰和確認加密算法的需要,單握手就需要6/7 個往返。接下來才是具體的http協(xié)議,每一次響應或者請求, 都要求客戶端和服務端對會話的內(nèi)容做加密/解密。=》所以對帶寬及cpu都有壓力
CA證書
需要CA認證機構頒發(fā),配合公網(wǎng)域名。
公網(wǎng)上要購買證書,然后在nginx等負載均衡中間件配置私鑰文件。
域名
要在公網(wǎng)開放https的,需要購買域名,域名和主體綁定。
前端安全性問題
XSS,跨站腳本攻擊(Cross Site Script) 。它指的是惡意攻擊者往Web頁面里插入惡意html代碼,當用戶瀏覽該頁之時,嵌入的惡意html代碼會被執(zhí)行。如:彈出廣告
CSRF,跨站點偽造請求(Cross Site Request Forgery)。顧名思義就是 通過偽造連接請求在用戶不知情的情況下,讓用戶以自己的身份來完成攻擊者需要達到的一些目的。如:釣魚網(wǎng)站
cookie劫持,通過獲取頁面的權限,在頁面中寫一個簡單的到惡意站點的請求,并攜帶用戶的cookie。 獲取cookie后通過cookie 就可以直以被盜用戶的身份登錄站點。這就是cookie 劫持。
項目升級為https:
由于https的網(wǎng)站內(nèi)嵌其它項目時,要求內(nèi)嵌的項目也要https認證的,否則瀏覽器安全限制打開不了。
ajax
Asynchronous JavaScript and XML,在服務器和客戶端之間充當了一個緩沖器
原理
- 通過XmlHttpRequest對象來向服務器發(fā)異步請求,從服務器獲得數(shù)據(jù),然后用javascript來操作DOM而局部更新頁面
- 本身繼承了XMLHttpRequest 對象,所有現(xiàn)代瀏覽器均支持 XMLHttpRequest 對象(IE5 和 IE6 使用 ActiveXObject),用于在后臺與服務器交換數(shù)據(jù)
- 由下列技術組合而成:
- 使用CSS和XHTML來表示;
- 使用DOM模型來交互和動態(tài)顯示;
- 使用XMLHttpRequest來和服務器進行異步通信;
- 使用javascript來綁定和調(diào)用
$.ajax({
type:'GET', //默認get
dataType:'json', //預期服務器返回的數(shù)據(jù)類型。如果不指定,jQuery 將自動根據(jù) HTTP 包 MIME 信息來智能判斷
contentType:'application/x-www-form-urlencoded', //發(fā)送信息至服務器時內(nèi)容編碼類型
url:encodeURI(''), //特殊字符需要編碼
timeout:10000, //設置請求超時時間(毫秒)。此設置將覆蓋全局設置
data:{}, //post時傳遞數(shù)據(jù)
async: true, //默認異步
cache: true,//默認值: true,dataType 為 script 和 jsonp 時默認為 false。設置為 false 將不緩存此頁面
sucess:function(data,textStatus){
},
error:function(XMLHttpRequset,textStatus,error){
}
});
-
好處:
- 頁面無刷新,異步方式不用打斷用戶的操作;
- 將一些服務器的工作轉(zhuǎn)嫁到客戶端;
- 基于標準化的并被廣泛支持的技術,不需要小插件等
-
缺點:
- ajax干掉了back按鈕,即對瀏覽器后退機制的破壞【google通過創(chuàng)建或使用一個隱藏的IFRAME來重現(xiàn)頁面上的變更】;
- ajax的邏輯處理對客戶端的安全掃描隱藏
Ajax不能重定向的問題
-
問題:發(fā)送一個接口請求,接口本身重定向到login界面;browser本身發(fā)送兩次請求,一個是接口的請求,response中是302狀態(tài),一個是重定向的請求,狀態(tài)是200,但不跳轉(zhuǎn)到login
9c2cab20.png
302 Found 是HTTP協(xié)議中的一個狀態(tài)碼(Status Code),可以簡單的理解為該資源原本確實存在,但已經(jīng)被臨時改變了位置
原因:默認ajax是不支持重定向,因為ajax本身就是局部刷新,不重新加載頁面。導致雖然客戶端接受到了重定向,并發(fā)出了請求,狀態(tài)碼也是200,但是瀏覽器并沒有跳轉(zhuǎn)
解決:
- 前端根據(jù)json數(shù)據(jù)自己跳轉(zhuǎn)login
- 后端執(zhí)行重定向的動作
java的重定向:
- 當使用轉(zhuǎn)發(fā)forward時,JSP容器將一個內(nèi)部的方法來調(diào)用目標頁面,新的頁面繼續(xù)處理同一個請求,而瀏覽器將不會知道這個過程;直接經(jīng)由server完成不同url訪問
RequestDispatcher rd = request.getRequestDispatcher("/error.jsp");
try {
rd.forward(request, response);
return; //如果不加,會報Cannot forward after response has been committed
}catch(Exception e){
}
- 重定向方式的含義是第一個頁面通知瀏覽器發(fā)送一個新的頁面請求
httpServletResponse.sendRedirect(url);
sendRedirect轉(zhuǎn)發(fā)更快,而且能保持request內(nèi)的對象=》可以解決頁面session傳遞問題;兩者在調(diào)用它們之前,都不能有內(nèi)容已經(jīng)被實際輸出到了客戶端。如果緩沖區(qū)中已經(jīng)有了一些內(nèi)容,這些內(nèi)容將被從緩沖區(qū)中清除
跨域
同源策略的限制。一般為了安全型,要求在域域名、端口號、協(xié)議上是一致的
不會判斷是否是同一個ip
但限制了注入iframe和ajax的應用,需要跨域訪問
- js跨域訪問方式:
使用document.domian來跨域
jsonp
JSON with Padding,動態(tài)創(chuàng)建script;同源策略不禁止在頁面中引用其他域的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"; //客戶端注冊一個jsonp,將callback名字傳遞給服務器
document.getElementsByTagName("head")[0].appendChild(JSONP); //將該源像web中元素引入
//服務器端以js語法創(chuàng)建callback函數(shù)
- 缺點:1、需要前后端協(xié)作;2、url使用相對路徑;3、jsonp是get形式,承載的信息量有限
使用window.name進行跨域數(shù)據(jù)傳輸
CORS
Cross-origin resource sharing 定義一種跨域訪問的機制,可以讓AJAX實現(xiàn)跨域訪問
實現(xiàn)此功能非常簡單,只需由服務器發(fā)送一個響應標頭即可;但需要特定瀏覽器支持
1ccbc2ad.png
支持的瀏覽器:
后臺設置:
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跨域問題
//或者指定域名
response.setHeader("Access-Control-Allow-Origin","name");
2、Spring MVC 4.2.5以后新增的支持跨域的注解@CrossOrigin
- 限制:
- 只能使用ajax請求,而不是form中action
-
Access-Control-Allow-Origin: *
允許任何來自任意域的跨域請求,那么久存在被 DDoS攻擊的可能
超時重試
如果應用不設置超時,則可能會導致請求響應慢,慢請求累積導致連鎖反應;
重試次數(shù)太多會導致多倍請求流量,即模擬了DDoS攻擊;讀服務天然適合重試,但寫服務大多不能重試
在進行代碼Review時,一定記得Review超時與重試機制
可能出現(xiàn)的超時節(jié)點:
- 代理層超時與重試:如Haproxy、Nginx、Twemproxy,這些組件實現(xiàn)代理功能,如Haproxy和Nginx可以實現(xiàn)請求的負載均衡
- Web容器超時:如Tomcat、Jetty等,提供HTTP服務運行環(huán)境的
- 中間件客戶端超時與重試:如JSF(京東SOA框架)、Dubbo、JMQ(京東消息中間件)
- 數(shù)據(jù)庫客戶端超時:如Mysql、Oracle,需要分別設置JDBC Connection、Statement的網(wǎng)絡連接/讀/寫超時時間。事務超時時間,獲取連接池連接等待時間
- 前端Ajax超時:瀏覽器通過Ajax訪問時的網(wǎng)絡連接/讀/寫超時時間
問題:
新平臺(端口彼此獨立,不共享session),后端接收到兩次請求,第1次是有session情況,第2次是訪問另外的端口跳轉(zhuǎn)到login界面(確定是filter中轉(zhuǎn)的)解決:
- 反向代理Nginx的配置
增加配置:
proxy_next_upstream http_502 http_504 error timeout invalid_header; #表示對error和timeout的進行重試到下一個節(jié)點
proxy_read_timeout 60s; #連接成功后,后端服務器響應時間(代理接收超時時間)
proxy_send_timeout 60; #后端服務器數(shù)據(jù)回傳時間(代理發(fā)送超時時間)
proxy_connect_timeout:75; #nginx連接后端的超時時間,一般不超過75s
- weblogic超時設置
一、web.xml
設置WEB應用程序描述符web.xml里的<session-timeout>元素。這個值以分鐘為單位,并覆蓋weblogic.xml中的TimeoutSecs屬性,此例表示Session將在54分鐘后過期。
<session-config>
<session-timeout>54</session-timeout>
</session-config>
當<session-timeout>設置為-2,表示將使用在weblogic.xml中設置的TimeoutSecs這個屬性值。
當<session-timeout>設置為-1,表示Session將永不過期,而忽略在weblogic.xml中設置的TimeoutSecs屬性值。該屬性值可以通過console控制臺來設置
二、weblogic.xml
設置WebLogic特有部署描述符weblogic.xml的<session-descriptor>元素的TimeoutSecs屬性。這個值以秒為單位。該文件放在項目的web-inf下。
<session-descriptor>
<session-param>
<param-name>TimeoutSecs</param-name>
<param-value>3600</param-value>
</session-param>
</session-descriptor>
默認值是3600秒
客戶端超時設置
Connection: keep-alive
每次http請求都要創(chuàng)建一個連接,而創(chuàng)建連接的過程需要消耗資源和時間,為了減少資源消耗,縮短響應時間,就需要重用連接;Keep-Alive: timeout=time
,即告知客戶端長連接超時時間
http/1.0默認是關閉長連接的,需要添加HTTP請求頭“Connection:Keep-Alive”才能啟用。而http/1.1默認啟用長連接,需要添加HTTP請求頭“Connection: close”才關閉ajax超時設置
Ajax 請求是限時的,所以錯誤警告被捕獲并處理后,可以用來提升用戶體驗。請求超時這個參數(shù)通常就保留其默認值,要不就通過 jQuery.ajaxSetup 來全局設定,很少為特定的請求重新設置 timeout 選項