摘要:如何解決跨域問題跨域原因由于瀏覽器的同源策略限制,只允許請求當前源域名協(xié)議端口的資源。同源策略同源策略是客戶端腳本尤其是的重要的安全度量標準。同源策略指的是協(xié)議,域名,端口相同,同源策略是一種安全協(xié)議。狀態(tài)表示客戶端已發(fā)送報文。
如何解決跨域問題:
跨域原因:由于瀏覽器的同源策略限制,XmlHttpRequest只允許請求當前源(域名、協(xié)議、端口)的資源。在腳本中發(fā)起HTTP請求,出于安全考慮,會被瀏覽器限制,html中通過標簽請求不存跨域:img,video,script文件,css文件等。
同源策略:同源策略是客戶端腳本(尤其是Javascript)的重要的安全度量標準。它最早出自Netscape Navigator2.0,其目的是防止某個文檔或腳本從多個不同源裝載。同源策略指的是:協(xié)議,域名,端口相同,同源策略是一種安全協(xié)議。一段腳本只能讀取來自同一來源的窗口和文檔的屬性。
為什么要有同源限制?
我們舉例說明:比如一個黑客程序,他利用Iframe把真正的銀行登錄頁面嵌到他的頁面上,當你使用真實的用戶名,密碼登錄時,他的頁面就可以通過Javascript讀取到你的表單中input中的內(nèi)容,這樣用戶名,密碼就輕松到手了。
跨域的幾種方式:
1>、JSONP:json+padding(內(nèi)填充),顧名思義,就是把JSON填充到一個盒子里。
原理:利用HTML的
/** jQuery獲取jsonp **/
$("#getJsonpByJquery").click(function () {
$.ajax({
url: "http://localhost:2701/home/somejsonp",
dataType: "jsonp",
jsonp: "callback",
success: function (data) {
console.log(data)
}
})
})
進階問題:
1,JSONP需要動態(tài)創(chuàng)建script標簽,需不需要處理這些script元素?怎么處理?
需要,可以監(jiān)聽script標簽的加載狀態(tài),當失敗或加載完成后移除script標簽并移除標簽上的監(jiān)聽事件,以及掛載在window上的回調(diào)函數(shù)。
2,JSONP請求的時候,服務(wù)器發(fā)生錯誤該怎么辦,前端怎么處理這個錯誤?
一般前端框架都會對跨域請求失敗是進行處理,比如JQuery中,當使用ajax或getJSON發(fā)送請求后會返回一個jqXHR對象。該對象實現(xiàn)了Promise協(xié)議,所以我們可以使用它的done、fail、always等接口來處理回調(diào)。例如我們可以用在它的fail回調(diào)中進行請求失敗時的錯誤處理:
var xhr = $.getJSON(...); xhr.fail(function(jqXHR, textStatus, ex) { alert("request failed, cause: " + ex.message); });
當遇到“非正常錯誤”時,除了IE7、8以外,JQuery的JSONP在較新的瀏覽器中全部會“靜默失敗”。但很多時候我們希望能夠捕獲和處理這種錯誤。實際上在這些瀏覽器中,
3>、通過修改document.domain來跨子域:將子域和主域的document.domain設(shè)為同一個主域.前提條件:這兩個域名必須屬于同一個基礎(chǔ)域名!而且所用的協(xié)議,端口都要一致,否則無法利用document.domain進行跨域。
4>、window.name實現(xiàn)跨域:window.name 的美妙之處:name 值在不同的頁面(甚至不同域名)加載后依舊存在,并且可以支持非常長的 name 值(2MB)。
原理:當在瀏覽器中打開一個頁面,或者在頁面中添加一個iframe時即會創(chuàng)建一個對應(yīng)的window對象,當頁面加載另一個新的頁面時,window的name屬性是不會變的。這樣就可以利用在頁面動態(tài)添加一個iframe然后src加載數(shù)據(jù)頁面,在數(shù)據(jù)頁面將需要的數(shù)據(jù)賦值給window.name。然而此時承載iframe的parent頁面還是不能直接訪問,不在同一域下iframe的name屬性,這時只需要將iframe再加載一個與承載頁面同域的空白頁面,即可對window.name進行數(shù)據(jù)讀取。
www.test.com下a.html頁:
www.domain.com下b.html頁:
5>、window.postMessage方法來跨域:
www.test.com下a.html頁:
www.domain.com下b.html頁:
6>、另可通過filder工具,或者本地起node來實現(xiàn)跨域。
XML和JSON的區(qū)別?XML:擴展標記語言,使用DTD文檔類型定義來組織數(shù)據(jù),格式統(tǒng)一,適合Web傳輸。
優(yōu)點:
1.格式統(tǒng)一,符合標準;
2.容易與其他系統(tǒng)進行遠程交互,數(shù)據(jù)共享方便;
3.擴展性好;
4.描述性比JSON好;
缺點:
1.文件龐大,格式復雜,傳輸數(shù)據(jù)量大;
2.客戶端不同瀏覽器解析XML方式不一致,需要重復編寫很多代碼;
3.服務(wù)器端和客戶端解析XML花費較多的資源和時間。
JSON:一種輕量級的數(shù)據(jù)交換格式,具有良好的可讀和便于快速編寫的特性。可在不同平臺之間進行數(shù)據(jù)交換。JSON采用兼容性很高的、完全獨立于語言文本格式。
優(yōu)點:
1,數(shù)據(jù)格式簡單,易于讀寫,傳輸數(shù)據(jù)量較??;
2.易于解析,客戶端可以簡單通過eval()進行JSON數(shù)據(jù)的讀??;
3.支持多種語言,便于服務(wù)端的解析;
缺點:
JSON只提供整體解析方案,而這種方法只在解析較少的數(shù)據(jù)時才能起到良好的效果;
XML通過SAX解析,可以不需要整個讀入文檔,就可以對解析出的內(nèi)容進行處理,是一種逐步解析的方法,也可以隨時終止,這種方案很適合于對大量數(shù)據(jù)的處理。
數(shù)據(jù)展示比較:
/** XML **/說說TCP傳輸?shù)娜挝帐炙拇螕]手策略?/** JSON **/ var country = { name: "中國", provinces: [ { name: "黑龍江", citys: { city: ["哈爾濱", "大慶"]} }, { name: "廣東", citys: { city: ["廣州", "深圳", "珠海"]} }, { name: "臺灣", citys: { city: ["臺北", "高雄"]} }, { name: "新疆", citys: { city: ["烏魯木齊"]} } ] } 中國 黑龍江 哈爾濱 大慶 廣東 廣州 深圳 珠海 臺灣 臺北 高雄 新疆 烏魯木齊
ACK:TCP協(xié)議規(guī)定,只有ACK=1時有效,也規(guī)定連接建立后所有發(fā)送的報文的ACK必須為1;
SYN: 在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接請求報文。對方若同意建立連接,則應(yīng)在響應(yīng)報文中使SYN=1和ACK=1. 因此, SYN置1就表示這是一個連接請求或連接接受報文。
FIN:即完,終結(jié)的意思, 用來釋放一個連接。當 FIN = 1 時,表明此報文段的發(fā)送方的數(shù)據(jù)已經(jīng)發(fā)送完畢,并要求釋放連接。
tcp標志位,有6種標示:
1.SYN(synchronous建立聯(lián)機)
2.ACK(acknowledgement 確認)
3.PSH(push傳送)
4.FIN(finish結(jié)束)
5.RST(reset重置)
6.URG(urgent緊急) Sequence number(順序號碼) Acknowledge number(確認號碼)狀態(tài)詳解:
1.CLOSED: 表示初始狀態(tài)。
2.LISTEN: 這個也是非常容易理解的一個狀態(tài),表示服務(wù)器端的某個SOCKET處于監(jiān)聽狀態(tài),可以接受連接了。
3.SYN_RCVD: 這個狀態(tài)表示接受到了SYN報文,在正常情況下,這個狀態(tài)是服務(wù)器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態(tài),很短暫,基本
上用netstat你是很難看到這種狀態(tài)的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最后一個ACK報文不予發(fā)送。因此這種狀態(tài)
時,當收到客戶端的ACK報文后,它會進入到ESTABLISHED狀態(tài)。
4.SYN_SENT: 這個狀態(tài)與SYN_RCVD遙想呼應(yīng),當客戶端SOCKET執(zhí)行CONNECT連接時,它首先發(fā)送SYN報文,因此也隨即它會進入到了SYN_SENT狀態(tài),并等待服務(wù)端的發(fā)送三次握手中的第2個報文。SYN_SENT狀態(tài)表示客戶端已發(fā)送SYN報文。
5.ESTABLISHED:這個容易理解了,表示連接已經(jīng)建立了。
6.FIN_WAIT_1: 這個狀態(tài)要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對方的FIN報文。而這兩種狀態(tài)的區(qū)別
是:FIN_WAIT_1狀態(tài)實際上是當SOCKET在ESTABLISHED狀態(tài)時,它想主動關(guān)閉連接,向?qū)Ψ桨l(fā)送了FIN報文,此時該SOCKET即
進入到FIN_WAIT_1狀態(tài)。而當對方回應(yīng)ACK報文后,則進入到FIN_WAIT_2狀態(tài),當然在實際的正常情況下,無論對方何種情況下,都應(yīng)該馬
上回應(yīng)ACK報文,所以FIN_WAIT_1狀態(tài)一般是比較難見到的,而FIN_WAIT_2狀態(tài)還有時常常可以用netstat看到。
7.FIN_WAIT_2:上面已經(jīng)詳細解釋了這種狀態(tài),實際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時還有點數(shù)據(jù)需要傳送給你,稍后再關(guān)閉連接。
8.TIME_WAIT: 表示收到了對方的FIN報文,并發(fā)送出了ACK報文,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FIN_WAIT_1狀態(tài)下,收到了對方同時帶FIN標志和ACK標志的報文時,可以直接進入到TIME_WAIT狀態(tài),而無須經(jīng)過FIN_WAIT_2狀態(tài)。
9.CLOSING: 這種狀態(tài)比較特殊,實際情況中應(yīng)該是很少見,屬于一種比較罕見的例外狀態(tài)。正常情況下,當你發(fā)送FIN報文后,按理來說是應(yīng)該先收到(或同時收到)對方的
ACK報文,再收到對方的FIN報文。但是CLOSING狀態(tài)表示你發(fā)送FIN報文后,并沒有收到對方的ACK報文,反而卻也收到了對方的FIN報文。什
么情況下會出現(xiàn)此種情況呢?其實細想一下,也不難得出結(jié)論:那就是如果雙方幾乎在同時close一個SOCKET的話,那么就出現(xiàn)了雙方同時發(fā)送FIN報
文的情況,也即會出現(xiàn)CLOSING狀態(tài),表示雙方都正在關(guān)閉SOCKET連接。
10.CLOSE_WAIT: 這種狀態(tài)的含義其實是表示在等待關(guān)閉。怎么理解呢?當對方close一個SOCKET后發(fā)送FIN報文給自己,你系統(tǒng)毫無疑問地會回應(yīng)一個ACK報文給對
方,此時則進入到CLOSE_WAIT狀態(tài)。接下來呢,實際上你真正需要考慮的事情是察看你是否還有數(shù)據(jù)發(fā)送給對方,如果沒有的話,那么你也就可以
close這個SOCKET,發(fā)送FIN報文給對方,也即關(guān)閉連接。所以你在CLOSE_WAIT狀態(tài)下,需要完成的事情是等待你去關(guān)閉連接。
11.LAST_ACK: 這個狀態(tài)還是比較容易好理解的,它是被動關(guān)閉一方在發(fā)送FIN報文后,最后等待對方的ACK報文。當收到ACK報文后,也即可以進入到CLOSED可用狀態(tài)了。
三次握手:
1、客戶端(Client)向服務(wù)端發(fā)送SYN包,即SYN=1,ACK=0,隨機產(chǎn)生seq number=3626544836,服務(wù)端(Serve)接收到SYN包,通過SYN=1,ACK=0 知道要求建立聯(lián)機;(第一次握手)
2、服務(wù)端收到請求后要確認聯(lián)機信息,向客戶端發(fā)送SYN包(syn=k),即ack number=3626544837,syn=1,ack=1,隨機產(chǎn)生seq=1739326486的包,服務(wù)端進入SYN_RECV狀態(tài);(第二次握手)
3、客戶端接收到服務(wù)發(fā)回的SYN+ACK包后,檢查ack number是否正確,即第一次發(fā)送的seq number+1,以及位碼ack是否為1,若正確,再次向服務(wù)端發(fā)送確認包ACK,即ack number=1739326487,ack=1,此包發(fā)送完畢后,服務(wù)端接收到后確認seq = seq + 1,ack = 1,則連接建立成功,雙方進入ESTABLISHED狀態(tài)。(第三次握手)
一個完整的三次握手就是:請求---應(yīng)答----再次確認----服務(wù)端收到確認建立連接
建立連接為什么要三次握手(兩次確認)?
兩次確認主要是為了防止已失效的連接請求報文段突然又傳送給了服務(wù)端,因而產(chǎn)生錯誤連接。
已失效的連接請求報文段發(fā)生情況:
1.假設(shè)客戶端向服務(wù)端發(fā)送一個建立連接的請求,請求報文由于網(wǎng)絡(luò)原因在某個網(wǎng)絡(luò)節(jié)點滯留了,客戶端長時間沒有收到服務(wù)端的確認,于是以為請求報文丟失,于是又再一次發(fā)送連接請求,然后這次收到確認并成功建立了連接,數(shù)據(jù)輸出完后,釋放了連接。
2.在釋放連接之后,結(jié)果第一次的連接請求到達了服務(wù)端,這時服務(wù)端會誤以為這是客戶端又重新發(fā)出了一次新的請求,于是向客戶端發(fā)送確認報文段,同意建立連接。
3.假如沒有采用三次握手,服務(wù)端這次發(fā)送確認后就建立了新的連接,并等待客戶端發(fā)來請求,可是客戶端實際情況并沒有發(fā)出請求,于是服務(wù)端很多資源就這樣浪費了。
4.如果采用三次握手,當服務(wù)端向客戶端發(fā)送確認報文段后,客戶端并不會再向服務(wù)端發(fā)送確認,于是服務(wù)端就知道客戶端并沒有要求建立連接。
若在握手過程中某個階段莫名中斷,TCP協(xié)議會再次以相同的順序發(fā)送相同的數(shù)據(jù)包。
四次揮手:
由于TCP連接是全雙工的,因此每個方向都必須多帶帶進行關(guān)閉。這個原則是當一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個FIN來終止這個方向的連接。收到一個 FIN只意味著這一方向上沒有數(shù)據(jù)流動,一個TCP連接在收到一個FIN后仍能發(fā)送數(shù)據(jù)。首先進行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方執(zhí)行被動關(guān)閉。
1、客戶端向服務(wù)端發(fā)送一個FIN,表示自己這方的數(shù)據(jù)已經(jīng)發(fā)送完畢,可以釋放連接。
2、服務(wù)端收到FIN后,發(fā)回一個ASK,確認已收到釋放連接通知,確認序號為收到的序號加1。
3、服務(wù)端確認自己這方的數(shù)據(jù)已經(jīng)發(fā)送完畢后,向客戶端發(fā)送一個FIN,表示要釋放連接。
4、客戶端收到FIN后,發(fā)回一個ASK報文確認,確認序號為收到的序號加1。
1、為什么建立連接時三次握手,關(guān)閉連接是4次握手?
1.這是因為服務(wù)端的LISTEN狀態(tài)下的SOCKET當收到SYN報文的建連請求后,它可以把ACK和SYN(ACK起應(yīng)答作用,而SYN起同步作用)放在一個報文里來發(fā)送。
2.但關(guān)閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方?jīng)]有數(shù)據(jù)發(fā)送給你了;但未必你所有的數(shù)據(jù)都全部發(fā)送給對方了,所以你未必會馬上會關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對方之后,再發(fā)送FIN報文給對方來表示你同意現(xiàn)在可以關(guān)閉連接了,所以它這里的ACK報文和FIN報文多數(shù)情況下都是分開發(fā)送的.
2.為什么TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)?
TCP和UDP的區(qū)別?1.這是因為雖然雙方都同意關(guān)閉連接了,而且握手的4個報文也都協(xié)調(diào)和發(fā)送完畢,按理可以直接回到CLOSED狀態(tài)(就好比從SYN_SEND狀態(tài)到ESTABLISH狀態(tài)那樣);
2.但是因為我們必須要假想網(wǎng)絡(luò)是不可靠的,你無法保證你最后發(fā)送的ACK報文會一定被對方收到,因此對方處于LAST_ACK狀態(tài)下的SOCKET可能會因為超時未收到ACK報文,而重發(fā)FIN報文,所以這個TIME_WAIT狀態(tài)的作用就是用來重發(fā)可能丟失的ACK報文。
TCP(Transmission Control Protocol,傳輸控制協(xié)議)是基于連接的協(xié)議,也就是說,在正式收發(fā)數(shù)據(jù)前,必須和對方建立可靠的連接。一個TCP連接必須要經(jīng)過三次“對話”才能建立起來
UDP(User Data Protocol,用戶數(shù)據(jù)報協(xié)議)是與TCP相對應(yīng)的協(xié)議。它是面向非連接的協(xié)議,它不與對方建立連接,而是直接就把數(shù)據(jù)包發(fā)送過去!
UDP適用于一次只傳送少量數(shù)據(jù)、對可靠性要求不高的應(yīng)用環(huán)境。
1.創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個異步調(diào)用對象;
2.通過XMLHttpRequest對象創(chuàng)建一個新的HTTP請求,并指定該HTTP請求的方法、URL及驗證信息;
3.設(shè)置響應(yīng)HTTP請求狀態(tài)變化的函數(shù);
4.發(fā)送HTTP請求;
5.獲取異步調(diào)用返回的數(shù)據(jù);
6.使用JavaScript和DOM實現(xiàn)局部刷新.
1、var xhr = new XMLHttpRequest(); // 創(chuàng)建xhr對象 2、xhr.open("GET", "example.php"); 3、xhr.onreadystatechange = function(){ if ( xhr.readyState == 4 && xhr.status == 200 ) { alert( xhr.responseText ); } else { alert( xhr.statusText ); } }; xhr.setRequestHeader( ..., ... ); 4、xhr.send();
readyState: unsigned short - 用于表示請求的五種狀態(tài):
具體有關(guān)XMLHttpRequest內(nèi)容可查看文章你不知道的 XMLHttpRequest、HTTP 最強資料大全
ajax的缺點和在IE下的問題:
ajax不支持瀏覽器back按鈕。
安全問題 AJAX暴露了與服務(wù)器交互的細節(jié)。
對搜索引擎的支持比較弱。
破壞了程序的異常機制。
不容易調(diào)試。
Web Worker 和webSocket?worker主線程:Web Worker可以分為兩種不同線程類型,一個是專用線程,一個是共享線程。
使用限制:
Web Worker無法訪問DOM節(jié)點;
Web Worker無法訪問全局變量或是全局函數(shù);
Web Worker無法調(diào)用alert()或者confirm之類的函數(shù);
Web Worker無法訪問window、document之類的瀏覽器全局變量;
專用線程示例:
主線程代碼 /** 1. 創(chuàng)建專用線程 **/ var worker = new Worker("dedicated.js"); /** 2. 接收來至工作線程 **/ worker.onmessage = function (event) { ... }; /** 3.發(fā)送 ArrayBuffer 數(shù)據(jù)代碼 **/ worker.postMessage(10000); /** 4.終止一個worker的執(zhí)行 **/ worker.terminate(); ------------------------------------------------ worker線程代碼 addEventListener("message", function(evt){ var date = new Date(); var currentDate = null; do { currentDate = new Date(); }while(currentDate - date < evt.data); postMessage(currentDate); }, false);
共享線程示例:
/** 1. 創(chuàng)建共享線程 **/ var worker = new SharedWorker("sharedworker.js", ’ mysharedworker ’ ); /** 2. 從端口接收數(shù)據(jù) , 包括文本數(shù)據(jù)以及結(jié)構(gòu)化數(shù)據(jù) **/ worker.port.onmessage = function (event) { define your logic here... }; /** 3. 向端口發(fā)送普通文本數(shù)據(jù) **/ worker.port.postMessage("put your message here … "); /** 向端口發(fā)送結(jié)構(gòu)化數(shù)據(jù) **/ worker.port.postMessage({ username: "usertext"; live_city: ["data-one", "data-two", "data-three","data-four"]});
socket:Websocket 其實是基于 HTML5 規(guī)范的一個新協(xié)議,它實現(xiàn)了瀏覽器與服務(wù)器全雙工通信,能更好的節(jié)省服務(wù)器資源和帶寬并達到實時通訊,它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸數(shù)據(jù)。
WebSocket 是一種雙向通信協(xié)議,在建立連接后,WebSocket 服務(wù)器和 Browser/Client Agent 都能主動的向?qū)Ψ桨l(fā)送或接收數(shù)據(jù),就像 Socket 一樣;
WebSocket 需要類似 TCP 的客戶端和服務(wù)器端通過握手連接,連接成功后才能相互通信。
HTTP請求與響應(yīng)交互圖:
WebSocket請求與響應(yīng)交互圖:
相對于傳統(tǒng) HTTP 每次請求-應(yīng)答都需要客戶端與服務(wù)端建立連接的模式,WebSocket 是類似 Socket 的 TCP 長連接的通訊模式,一旦 WebSocket 連接建立后,后續(xù)數(shù)據(jù)都以幀序列的形式傳輸。在客戶端斷開 WebSocket 連接或 Server 端斷掉連接前,不需要客戶端和服務(wù)端重新發(fā)起連接請求。在海量并發(fā)及客戶端與服務(wù)器交互負載流量大的情況下,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢,且客戶端發(fā)送和接受消息是在同一個持久連接上發(fā)起,實時性優(yōu)勢明顯。
WebSocket 通訊請求響應(yīng)報文:
客戶端連接報文:
可以看到,客戶端發(fā)起的 WebSocket 連接報文類似傳統(tǒng) HTTP 報文,"Upgrade:websocket"參數(shù)值表明這是 WebSocket 類型請求,“Sec-WebSocket-Key”是 WebSocket 客戶端發(fā)送的一個 base64 編碼的密文,要求服務(wù)端必須返回一個對應(yīng)加密的“Sec-WebSocket-Accept”應(yīng)答,否則客戶端會拋出“Error during WebSocket handshake”錯誤,并關(guān)閉連接。
服務(wù)端響應(yīng)報文:
“Sec-WebSocket-Accept”的值是服務(wù)端采用與客戶端一致的密鑰計算出來后返回客戶端的。,“HTTP/1.1 101 Switching Protocols”表示服務(wù)端接受 WebSocket 協(xié)議的客戶端連接,經(jīng)過這樣的請求-響應(yīng)處理后,客戶端服務(wù)端的 WebSocket 連接握手成功, 后續(xù)就可以進行 TCP 通訊了。
WebSocket 實現(xiàn):
支持瀏覽器:
實現(xiàn)代碼:
/** 申請一個WebSocket對象,參數(shù)為需要連接的服務(wù)端地址,協(xié)議的URL使用ws://開頭,安全的WebSocket協(xié)議使用wss://開頭 **/ var ws = new WebSocket("ws://..."); /** 當 Browser 和 WebSocketServer 連接成功后,會觸發(fā) onopen 消息 **/ ws.onopen = function(){ws.send(“Test!”);}; /** 如果連接失敗,發(fā)送、接收數(shù)據(jù)失敗或者處理數(shù)據(jù)出現(xiàn)錯誤,browser 會觸發(fā) onerror 消息 **/ ws.onerror = function(evt){console.log("error")}; /** 當 Browser 接收到 WebSocketServer 發(fā)送過來的數(shù)據(jù)時,就會觸發(fā) onmessage 消息,參數(shù) evt 中包含 Server 傳輸過來的數(shù)據(jù) **/ ws.onmessage = function(evt){console.log(evt.data);ws.close();}; /** 當 Browser 接收到 WebSocketServer 端發(fā)送的關(guān)閉連接請求時,就會觸發(fā) onclose 消息 **/ ws.onclose = function(evt){console.log(“WebSocketClosed!”);};
談?wù)剬TTP的理解?所有的操作都是采用異步回調(diào)的方式觸發(fā),這樣不會阻塞 UI,可以獲得更快的響應(yīng)時間,更好的用戶體驗。
http中文叫超文本傳輸協(xié)議,是客戶端與服務(wù)端之間傳輸數(shù)據(jù)規(guī)定的一種協(xié)議,通常承載與TCP協(xié)議之上,基于請求與響應(yīng)模式的、無狀態(tài)的、應(yīng)用層的協(xié)議,常基于TCP的連接方式。
特點:
支持客戶/服務(wù)器模式;
簡單快速:客戶向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快;
靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀蒀ontent-Type加以標記;
無連接:無連接的含義是限制每次連接只處理一個請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時間。
無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時它的應(yīng)答就較快。在實際應(yīng)用當中并不是完全這樣的,引入了Cookie和Session機制來關(guān)聯(lián)請求。
HTTP報文:
請求報文:由請求行、請求頭、請求體構(gòu)成,每一行的末尾都有回車和換行,在請求頭和請求體之間還有一個空行。
請求行指定由請求方法、請求URL、協(xié)議版本組成;
請求頭是由鍵值對形式存在的,例如content-type:application/json;
空行;
請求體就是要傳輸?shù)臄?shù)據(jù);
響應(yīng)報文:由狀態(tài)行、響應(yīng)頭、響應(yīng)體組成。
狀態(tài)行由協(xié)議版本、狀態(tài)碼、狀態(tài)短語組成;
響應(yīng)頭也是由鍵值對形式存在,例如:
Content-Length: 563
Content-Type: text/html
空行;
響應(yīng)體即要傳輸?shù)臄?shù)據(jù);
HTTP請求方法:
GET:獲取資源;
POST:傳輸實體主體; POST方法用來傳輸實體主體。POST與GET的區(qū)別之一就是目的不同,二者之間的區(qū)別會在文章的最后詳細說明。雖然GET方法也可以傳輸,但是一般不用,因為GET的目的是獲取,POST的目的是傳輸。
PUT:傳輸文件; PUT方法用來傳輸文件。類似FTP協(xié)議,文件內(nèi)容包含在請求報文的實體中,然后請求保存到URL指定的服務(wù)器位置。
HEAD:獲得報文首部; HEAD方法類似GET方法,但是不同的是HEAD方法不要求返回數(shù)據(jù)。用于確認URI的有效性及資源更新時間等。
DELETE:刪除文件; DELETE方法用來刪除文件,是與PUT相反的方法。DELETE是要求返回URL指定的資源。
OPTIONS:詢問支持的方法; 因為并不是所有的服務(wù)器都支持規(guī)定的方法,為了安全有些服務(wù)器可能會禁止掉一些方法例如DELETE、PUT等。那么OPTIONS就是用來詢問服務(wù)器支持的方法。
TRACE:追蹤路徑; TRACE方法是讓Web服務(wù)器將之前的請求通信還回給客戶端的方法。這個方法并不常用。
CONNECT:要求用隧道協(xié)議連接代理; CONNECT方法要求在與代理服務(wù)器通信時建立隧道,實現(xiàn)用隧道協(xié)議進行TCP通信。主要使用SSL/TLS協(xié)議對通信內(nèi)容加密后傳輸。
HTTP的響應(yīng)狀態(tài)碼:
get和post區(qū)別:
get請求數(shù)據(jù)會附加在url之后,以?分割url地址和傳輸數(shù)據(jù),多個參數(shù)用&鏈接。傳輸數(shù)據(jù)會受到url長度的限制。并且get請求由于把請求數(shù)據(jù)都放在URL上,這樣很容易被他人拿到數(shù)據(jù)。比如登錄頁面,用戶名和密碼都會暴露在URL上。
post請求會把數(shù)據(jù)放在請求實體中,這樣理論上是沒有大小限制,并且POST可能會修改服務(wù)器上的資源的請求。
常用狀態(tài)碼:
200:OK;
代表請求被正常的處理成功了。
204:No Content;
請求處理成功,但是沒有數(shù)據(jù)實體返回,也不允許有實體返回。比如說HEAD請求,可能就會返回204 No Content,因為HEAD就是只獲取頭信息。
205:Reset Content;
不但沒有數(shù)據(jù)實體返回,而且還需要重置表單,方便用戶再次輸入。
206:Partial Content;
這是客戶端使用Content-Range指定了需要的實體數(shù)據(jù)的范圍,然后服務(wù)端處理請求成功之后返回用戶需要的這一部分數(shù)據(jù)而不是全部,執(zhí)行的請求就是GET。
301:Moved Permanently;
代表永久性定向。該狀態(tài)碼表示請求的資源已經(jīng)被分配了新的URL,以后應(yīng)該使用資源現(xiàn)在指定的URL。也就是說如果已經(jīng)把資源對應(yīng)的URL保存為書簽了,這是應(yīng)該按照Location首部字段提示的URL重新保存。
302:Found;
代表臨時重定向。該狀態(tài)碼表示請求的資源已經(jīng)被分配了新的URL,但是和301的區(qū)別是302代表的不是永久性的移動,只是臨時的。就是說這個URL還可能會發(fā)生改變。如果保存成書簽了也不會更新。
303:See Other;
和302的區(qū)別是303明確規(guī)定客戶端應(yīng)當使用GET方法。
304:Not Modified;
該狀態(tài)碼表示客戶端發(fā)送附帶條件請求時,服務(wù)器端允許請求訪問資源,但是沒有滿足條件,瀏覽器在接收到個狀態(tài)碼后,會使用瀏覽器已緩存的文件。304狀態(tài)碼返回時不包含任何數(shù)據(jù)實體。304雖然被劃分在3XX中但是和重定向沒有關(guān)系。
客戶端請求一個頁面(A)。 服務(wù)器返回頁面A,并在給A加上一個ETag。 客戶端展現(xiàn)該頁面,并將頁面連同ETag一起緩存。
客戶再次請求頁面A,并將上次請求時服務(wù)器返回的ETag一起傳遞給服務(wù)器。
服務(wù)器檢查該ETag,并判斷出該頁面自上次客戶端請求之后還未被修改,直接返回響應(yīng)304(未修改——Not
Modified)和一個空的響應(yīng)體。
307:Temporary Redirect;
臨時重定向,與302 Found相同,但是302會把POST改成GET,而307就不會。
400:Bad Request;
400表示請求報文中存在語法錯誤。需要修改后再次發(fā)送。
401:Unauthorized;
該狀態(tài)碼表示未授權(quán),請求要求身份驗證。對于登錄后請求的網(wǎng)頁,服務(wù)器可能返回此響應(yīng)。
403:Forbidden;
表明請求訪問的資源被拒絕了。沒有獲得服務(wù)器的訪問權(quán)限,IP被禁止等。
404:Not Found;
表明請求的資源在服務(wù)器上找不到。當然也可以在服務(wù)器拒絕請求且不想說明理由時使用。
408:Request Timeout;
表示客戶端請求超時,就是在客戶端和服務(wù)器建立連接后服務(wù)器在一定時間內(nèi)沒有收到客戶端的請求。
500:Internal Server Error;
表明服務(wù)器端在執(zhí)行請求時發(fā)生了錯誤,很有可能是服務(wù)端程序的Bug或者臨時故障。
503:Service Unavailable;
表明服務(wù)器暫時處于超負載或正在進行停機維護,現(xiàn)在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入Retry-After字段再返回給客戶端。
504:Getaway Timeout;
網(wǎng)關(guān)超時,是代理服務(wù)器等待應(yīng)用服務(wù)器響應(yīng)時的超時,和408 Request Timeout的卻別就是504是服務(wù)器的原因而不是客戶端的原因。
HTTP協(xié)議通常承載于TCP協(xié)議之上,在HTTP和TCP之間添加一個安全協(xié)議層(SSL或TSL),這個時候,就成了我們常說的HTTPS。
默認HTTP的端口號為80,HTTPS的端口號為443。
瀏覽器地址欄輸入一個URL回車后,發(fā)生了什么?為什么HTTPS安全?
因為網(wǎng)絡(luò)請求需要中間有很多的服務(wù)器路由器的轉(zhuǎn)發(fā)。中間的節(jié)點都可能篡改信息,而如果使用HTTPS,密鑰在你和終點站才有。https之所以比http安全,是因為他利用ssl/tls協(xié)議傳輸。它包含證書,卸載,流量轉(zhuǎn)發(fā),負載均衡,頁面適配,瀏覽器適配,refer傳遞等,保障了傳輸過程的安全性。
瀏覽器通過DNS查詢查找出域名的IP地址:瀏覽器緩存 >> 系統(tǒng)緩存 >> 路由器緩存 >> ISP DNS 緩存 >> 遞歸搜索
通過TCP三次握手與服務(wù)器建立連接;
瀏覽器發(fā)送http請求報文;
服務(wù)器返回http響應(yīng)報文;
斷開TCP連接;
瀏覽器解析HTML/SVG/XHTML,解析這三種文件產(chǎn)生一個 DOM Tree;
在瀏覽器顯示HTML時,它會注意到需要獲取其他地址內(nèi)容的標簽。這時,瀏覽器會發(fā)送一個獲取請求來重新獲得這些文件。這些文件就包括CSS/JS/圖片等資源,這些資源的地址都要經(jīng)歷一個和HTML讀取類似的過程。所以瀏覽器會在DNS中查找這些域名,發(fā)送請求,重定向等等…;
瀏覽器解析 CSS 會產(chǎn)生 CSS 規(guī)則樹;
解析JavaScript腳本,主要是通過 DOM API 和 CSSOM API 來操作 DOM Tree 和 CSS Rule Tree
瀏覽器解析渲染過程是逐步完成的,為了更好的用戶體驗,渲染引擎將會盡可能早的將內(nèi)容呈現(xiàn)到屏幕上,并不會等到所有的html都解析完成之后再去構(gòu)建和布局render樹。它是解析完一部分內(nèi)容就顯示一部分內(nèi)容,同時,可能還在通過網(wǎng)絡(luò)下載其余內(nèi)容。
Reflow(回流):瀏覽器要花時間去渲染,當它發(fā)現(xiàn)了某個部分發(fā)生了變化影響了布局,那就需要倒回去重新渲染。
Repaint(重繪):如果只是改變了某個元素的背景顏色,文字顏色等,不影響元素周圍或內(nèi)部布局的屬性,將只會引起瀏覽器的repaint,重畫某一部分。
編寫CSS注意事項:
CSS選擇符是從右到左進行匹配的。#nav li 會去找所有的li,然后再去確定它的父元素是不是#nav。
dom深度盡量淺;
減少inline javascript、css的數(shù)量;
使用現(xiàn)代合法的css屬性;
不要為id選擇器指定類名或是標簽,因為id可以唯一確定一個元素;
避免后代選擇符,盡量使用子選擇符。原因:子元素匹配符的概率要大于后代元素匹配符。后代選擇符;#tp p{} 子選擇符:#tp>p{};
避免使用通配符,舉一個例子,.mod .hd *{font-size:14px;} 根據(jù)匹配順序,將首先匹配通配符,也就是說先匹配出通配符,然后匹配.hd(就是要對dom樹上的所有節(jié)點進行遍歷他的父級元素),然后匹配.mod,這樣的性能耗費可想而知.
script標簽為什么要放在body結(jié)束標簽之前?
因為js的下載和執(zhí)行會阻塞Dom樹的構(gòu)建。
載入后馬上執(zhí)行;
執(zhí)行時會阻塞頁面后續(xù)的內(nèi)容(包括頁面的渲染、其它資源的下載)。原因:因為瀏覽器需要一個穩(wěn)定的DOM樹結(jié)構(gòu),而JS中很有可能有 代碼直接改變了DOM樹結(jié)構(gòu),比如使用 document.write 或appendChild,甚至是直接使用的location.href進行跳轉(zhuǎn),瀏覽器為了防止出現(xiàn)JS修改DOM樹,需要重新構(gòu)建DOM樹的情況,所以 就會阻塞其他的下載和呈現(xiàn)。
減少 JavaScript 對性能的影響的方法:
將所有的script標簽放到頁面底部,也就是body閉合標簽之前,這能確保在腳本執(zhí)行前頁面已經(jīng)完成了DOM樹渲染。
盡可能地合并腳本。頁面中的script標簽越少,加載也就越快,響應(yīng)也越迅速。無論是外鏈腳本還是內(nèi)嵌腳本都是如此。
采用無阻塞下載 JavaScript 腳本的方法:
(1)、使用script標簽的 defer 屬性(僅適用于 IE 和 Firefox 3.5 以上版本);
(2)、使用動態(tài)創(chuàng)建的script元素來下載并執(zhí)行代碼;
(3)、按需異步載入js;
SessionStorage 和 localStorage 是HTML5 storage API 提供的, 可以把數(shù)據(jù)保存在本地,避免了數(shù)據(jù)在瀏覽器和服務(wù)器之間不必要的通信。sessionStorage,localStorage, cookie 都是在瀏覽器存儲的數(shù)據(jù)。
不同:
cookie數(shù)據(jù)始終在同源http中攜帶,即使不需要,也會在瀏覽器和服務(wù)器間來回傳遞。Storage只存在本地;
cookie數(shù)據(jù)有路徑概念,可以限制cookie只能在某路徑下;
cookie:4k Storage:5M;
sessionStorage: 僅在當前瀏覽器關(guān)閉前有效,localStorage:始終有效,cookie:過期之前有效;
sessionStorage:在打開的不同瀏覽器窗口不共享,即使同一頁面,localStorage:在同源頁面共享,cookie:同源頁面共享
待續(xù).....2017.5.31
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/83245.html
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
摘要:獲取的對象范圍方法獲取的是最終應(yīng)用在元素上的所有屬性對象即使沒有代碼,也會把默認的祖宗八代都顯示出來而只能獲取元素屬性中的樣式。因此對于一個光禿禿的元素,方法返回對象中屬性值如果有就是據(jù)我測試不同環(huán)境結(jié)果可能有差異而就是。 花了很長時間整理的前端面試資源,喜歡請大家不要吝嗇star~ 別只收藏,點個贊,點個star再走哈~ 持續(xù)更新中……,可以關(guān)注下github 項目地址 https:...
摘要:前端面試每日題,以面試題來驅(qū)動學習,每天進步一點讓努力成為一種習慣,讓奮斗成為一種享受相信堅持的力量項目地址前端面試每日推薦歡迎跟一起折騰前端,系統(tǒng)整理前端知識,目前正在折騰,打算打通算法與數(shù)據(jù)結(jié)構(gòu)的任督二脈。 《論語》,曾子曰:吾日三省吾身(我每天多次反省自己)。 前端面試每日3+1題,以面試題來驅(qū)動學習,每天進步一點! 讓努力成為一種習慣,讓奮斗成為一種享受!相信 堅持 的力量...
摘要:前端面試每日題,以面試題來驅(qū)動學習,每天進步一點讓努力成為一種習慣,讓奮斗成為一種享受相信堅持的力量項目地址前端面試每日推薦歡迎跟一起折騰前端,系統(tǒng)整理前端知識,目前正在折騰,打算打通算法與數(shù)據(jù)結(jié)構(gòu)的任督二脈。 《論語》,曾子曰:吾日三省吾身(我每天多次反省自己)。 前端面試每日3+1題,以面試題來驅(qū)動學習,每天進步一點! 讓努力成為一種習慣,讓奮斗成為一種享受!相信 堅持 的力量...
摘要:畢業(yè)之后就在一直合肥小公司工作,沒有老司機沒有技術(shù)氛圍,在技術(shù)的道路上我只能獨自摸索。于是乎,我果斷辭職,在新年開工之際來到杭州,這里的互聯(lián)網(wǎng)公司應(yīng)該是合肥的幾十倍吧。。。。 畢業(yè)之后就在一直合肥小公司工作,沒有老司機、沒有技術(shù)氛圍,在技術(shù)的道路上我只能獨自摸索。老板也只會畫餅充饑,前途一片迷茫看不到任何希望。于是乎,我果斷辭職,在新年開工之際來到杭州,這里的互聯(lián)網(wǎng)公司應(yīng)該是合肥的幾十...
摘要:手冊網(wǎng)超級有用的前端基礎(chǔ)技術(shù)面試問題收集前端面試題目及答案匯總史上最全前端面試題含答案常見前端面試題及答案經(jīng)典面試題及答案精選總結(jié)前端面試過程中最容易出現(xiàn)的問題前端面試題整理騰訊前端面試經(jīng)驗前端基礎(chǔ)面試題部分最新前端面試題攻略前端面試前端入 手冊網(wǎng):http://www.shouce.ren/post/index 超級有用的前端基礎(chǔ)技術(shù)面試問題收集:http://www.codec...
閱讀 1783·2021-11-12 10:35
閱讀 1705·2021-08-03 14:02
閱讀 2771·2019-08-30 15:55
閱讀 2103·2019-08-30 15:54
閱讀 844·2019-08-30 14:01
閱讀 2492·2019-08-29 17:07
閱讀 2316·2019-08-26 18:37
閱讀 3106·2019-08-26 16:51