1.get數據是存放在url以後,以?分割url和傳輸數據,參數之間以&相連; post方法是把提交的數據放在http包的Body中 2.get提交的數據大小有限制,(由於瀏覽器對url的長度有限制),post的方法提交的數據沒有限制 3.get須要request.queryString來獲取變量的值,而post方式經過request.from來獲取變量的值 4.get的方法提交數據,會帶來安全問題,好比登陸一個頁面,經過get的方式提交數據,用戶名和密碼就會出如今url上
1、TCP面向鏈接(如打電話要先撥號創建鏈接);UDP是無鏈接的,即發送數據以前不須要創建鏈接 2、TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保 證可靠交付 3、TCP面向字節流,其實是TCP把數據當作一連串無結構的字節流;UDP是面向報文的 UDP沒有擁塞控制,所以網絡出現擁塞不會使源主機的發送速率下降(對實時應用頗有用,如IP電話,實時視頻會議等) 4、每一條TCP鏈接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通訊 5、TCP首部開銷20字節;UDP的首部開銷小,只有8個字節 六、TCP的邏輯通訊信道是全雙工的可靠信道,UDP則是不可靠信道
咱們知道TCP經過一個定時器(timer)採樣了RTT並計算RTO,可是,若是網絡上的延時忽然增長,那麼,TCP對這個事作出的應對只有重傳數據,
然而重傳會致使網絡的負擔更重,因而會致使更大的延遲以及更多的丟包,這就致使了惡性循環,最終造成「網絡風暴」 —— TCP的擁塞控制機制就是用於應對這種狀況。
首先須要瞭解一個概念,爲了在發送端調節所要發送的數據量,定義了一個「擁塞窗口」(Congestion Window),
在發送數據時,將擁塞窗口的大小與接收端ack的窗口大小作比較,取較小者做爲發送數據量的上限。
擁塞控制主要是四個算法: //1.慢啓動:意思是剛剛加入網絡的鏈接,一點一點地提速,不要一上來就把路佔滿。 鏈接建好的開始先初始化cwnd = 1,代表能夠傳一個MSS大小的數據。 每當收到一個ACK,cwnd++; 呈線性上升 每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升 閾值ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入「擁塞避免算法」
//2.擁塞避免:當擁塞窗口 cwnd 達到一個閾值時,窗口大小再也不呈指數上升,而是以線性上升,避免增加過快致使網絡擁塞。 每當收到一個ACK,cwnd = cwnd + 1/cwnd 每當過了一個RTT,cwnd = cwnd + 1 擁塞發生:當發生丟包進行數據包重傳時,表示網絡已經擁塞。分兩種狀況進行處理: 等到RTO超時,重傳數據包 sshthresh = cwnd /2 cwnd 重置爲 1
//3.進入慢啓動過程 在收到3個duplicate ACK時就開啓重傳,而不用等到RTO超時 sshthresh = cwnd = cwnd /2 進入快速恢復算法——Fast Recovery
//4.快速恢復:至少收到了3個Duplicated Acks,說明網絡也不那麼糟糕,能夠快速恢復。 cwnd = sshthresh + 3 * MSS (3的意思是確認有3個數據包被收到了) 重傳Duplicated ACKs指定的數據包 若是再收到 duplicated Acks,那麼cwnd = cwnd +1 若是收到了新的Ack,那麼,cwnd = sshthresh ,而後就進入了擁塞避免的算法了。
其實同步和異步, 不管如何,作事情的時候都是隻有一條流水線(單線程), //同步和異步的差異就在於這條流水線上各個流程的執行順序不一樣。 同步任務,只有前一個任務執行完畢,才能執行後一個任務; 異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務, 只有等主線程任務執行完畢,"任務隊列"開始通知主線程,請求執行任務,該任務纔會進入主線程執行。
總結:同步、異步:只是對於熱水壺。普通水壺表明同步;響水壺表明異步。雖然都能幹活,但響水壺能夠在本身完工以後,提示小楊水開了。 阻塞、非阻塞:僅僅表明小楊,立等的屬於阻塞(1,3);幹別的事了屬於非阻塞(2,4)。 因此在上述同步阻塞、同步非阻塞、異步阻塞、異步非阻塞中,異步非阻塞狀況下效率較高。
HTTP協議是使用TCP協議做爲其傳輸層協議的,在拿到服務器的IP地址後,瀏覽器客戶端會與服務器創建TCP鏈接。該過程包括三次握手:
三次握手主要是爲了防止已經失效的請求報文字段發送給服務器,浪費資源。
詳細版javascript
SYN (同步序列編號)ACK(確認字符)css
客戶端與服務器四次揮手,斷開tcp鏈接。
詳細版:
這是由於服務端在LISTEN狀態下,收到創建鏈接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。
而關閉鏈接時,當收到對方的FIN報文時,僅僅表示對方再也不發送數據了可是還能接收數據,己方也未必所有數據都發送給對方了,
因此己方能夠當即close,也能夠發送一些數據給對方後,再發送FIN報文給對方來表示贊成如今關閉鏈接,所以,己方ACK和FIN通常都會分開發送。
http傳輸的數據都是未加密的,也就是明文的,網景公司設置了SSL協議來對http協議傳輸的數據進行加密處理,
簡單來講https協議是由http和ssl協議構建的可進行加密傳輸和身份認證的網絡協議,比http協議的安全性更高。
主要的區別以下:
1.超文本的傳輸協議,是用於從萬維網服務器超文本傳輸到本地資源的傳輸協議 2.基於TCP/IP通訊協議來傳遞數據(HTML,圖片資源) 3.基於運用層的面向對象的協議,因爲其簡潔、快速的方法、適用於分佈式超媒體信息系統 4.http請求信息request: 請求行(request line)、請求頭部(header),空行和請求數據四部分構成 請求行,用來講明請求類型,要訪問的資源以及所使用的HTTP版本. 請求頭部,用來講明服務器要使用的附加信息 空行,請求頭部後面的空行是必須的 請求數據也叫主體,能夠添加任意的其餘數據。 5.http相應信息Response 狀態行、消息報頭、空行和響應正文 狀態行,由HTTP協議版本號, 狀態碼, 狀態消息 三部分組成 消息報頭,用來講明客戶端要使用的一些附加信息 空行,消息報頭後面的空行是必須的 響應正文,服務器返回給客戶端的文本信息。
客戶端在使用HTTPS方式與Web服務器通訊時有如下幾個步驟,如圖所示。
正文:http協議無狀態中的【狀態】到底指的是什麼?!
先來看這句話的另外兩個概念:(標準的http協議是無狀態的,無鏈接的)
標準的http協議指的是不包括cookies, session,application的http協議,他們都不屬於標準協議,雖然各類網絡應用提供商,實現語言、web容器等,都默認支持它
無鏈接指的是什麼
每個訪問都是無鏈接,服務器挨個處理訪問隊列裏的訪問,處理完一個就關閉鏈接,這事兒就完了,而後處理下一個新的
無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接
對於【無狀態】,我看到不少隔着一層磨砂玻璃同樣的模糊說法(官方或者教程裏的說法),看着很是難受(但其實算是對的)
(後來我發現我爲何以爲它看着難受了,由於他們引入了不少新的,並且明顯是一個可能用在不少地方的廣義名詞,這些詞最大的做用就是,混淆概念,下面我標註了)
協議對於事務處理沒有記憶能力【事物處理】【記憶能力】
對同一個url請求沒有上下文關係【上下文關係】
每次的請求都是獨立的,它的執行狀況和結果與前面的請求和以後的請求是無直接關係的,它不會受前面的請求應答狀況直接影響,也不會直接影響後面的請求應答狀況【無直接聯繫】【受直接影響】
服務器中沒有保存客戶端的狀態,客戶端必須每次帶上本身的狀態去請求服務器【狀態】
//優勢 使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器; HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程當中不被竊取、改變,確保數據的完整性。 HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增長了中間人攻擊的成本。 谷歌曾在2014年8月份調整搜索引擎算法,並稱「比起同等HTTP網站,採用HTTPS加密的網站在搜索結果中的排名將會更高」。 //缺點 https握手階段比較費時,會使頁面加載時間延長50%,增長10%~20%的耗電。 https緩存不如http高效,會增長數據開銷。 SSL證書也須要錢,功能越強大的證書費用越高。 SSL證書須要綁定IP,不能再同一個ip上綁定多個域名,ipv4資源支持不了這種消耗。
//http1.1相比1.0有以下幾點不一樣: 1.默認支持長鏈接; 2.帶寬優化,並支持斷點續傳; 3.新增例如ETag,If-None-Match等更多的緩存控制策略; 4.Host頭域; 5.新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示服務器上的某個資源被永久性的刪除; //http2.0與1.1相比有以下幾點不一樣: 1.多路複用,能夠作到在一個鏈接並行的處理多個請求; 2.header壓縮; 3.服務端推送; 4.解析格式不一樣。HTTP1.0和1.1的解析是基於文本,2.0的協議解析採用二進制格式,實現方便且健壯;
首先補充一下,http和https的區別,相比於http,https是基於ssl加密的http協議 簡要歸納:http2.0是基於1999年發佈的http1.0以後的首次更新。 一、提高訪問速度(能夠對於,請求資源所需時間更少,訪問速度更快,相比http1.0) 二、容許多路複用:多路複用容許同時經過單一的HTTP/2鏈接發送多重請求-響應信息。
改善了:在http1.1中,瀏覽器客戶端在同一時間,針對同一域名下的請求有必定數量限制(鏈接數量),超過限制會被阻塞。 3、二進制分幀:HTTP2.0會將全部的傳輸信息分割爲更小的信息或者幀,並對他們進行二進制編碼 4、首部壓縮 五、服務器端推送
簡潔版:
1.對稱加密: 加密數據和解密數據的密鑰如出一轍,因此對於多個有數據交換需求的個體,兩兩之間共同維護一把密鑰,這個帶來的成本基本是不可接受的。(老百姓不會啊)
2.非對稱加密:加密數據的(公鑰),跟解密數據的(私鑰)是不同的。html
經過公鑰加密的數據,只能經過私鑰解開。經過私鑰加密的數據,只能經過公鑰解開,因此非對稱加密是單項安全的。前端
可是公鑰,公開的密鑰,誰均可以查到,因此非對稱加密只有公鑰向私鑰發的那一條是安全的(單項)java
詳細版:
1.對稱加密:甲和乙是一對生意搭檔,他們住在不一樣的城市。因爲生意上的須要,他們常常會相互之間郵寄重要的貨物。
爲了保證貨物的安全,他們商定製做一個保險盒(即通過算法加密),將物品放入其中。
他們打造了兩把相同的鑰匙(雙方持有對稱、相同的祕鑰)分別保管,以便在收到包裹時用這個鑰匙打開保險盒,以及在郵寄貨物前用這把鑰匙鎖上保險盒。
這樣看來也印證上面所說的對稱加密最重要的問題在於如何將「鑰匙」安全的送達並保存。 2.非對稱加密:A和B兩家公司,須要交流重要信息(好比交易金額發起和交易結果通知)。
A須要保證本身的發起金額準確,必須進行信息加密,B公司是實際金額的操做者(幫A公司代收代付),A使用B給的公鑰加密數據,B使用本身的私鑰解密執行金額交易。
這樣只有和B公司合做的並持有B公司發放的公鑰才能發起交易。反之,A公司也只識別本身給了公鑰的B公司加密的數據。這樣就是最基本的非對稱加密的用法。
可是有一個新的問題是,假如一樣持有B公司公鑰的C公司模擬或從中修改了A公司發起數據並加密傳給了B,B不知道是C僞造的執行了操做就會給A帶來經濟損失。
因此新的問題出現了:身份認證和信息完整性必須驗證! A:將被髮送文件用SHA編碼加密產生128bit的數字摘要,用本身的私用密鑰對摘要再加密,這就造成了數字簽名。而後將使用B公鑰加密的密文和加密的摘要同時傳給B。 B:用A公共密鑰對數字簽名解密(這裏保證了只有A的身份),同時對收到的密文使用本身的私鑰解密,在用SHA編碼加密產生又一摘要。
將解密後的摘要和用SHA編碼加密產生的又一摘要相互對比。如二者一致,則說明傳送過程當中信息沒有被破壞或篡改過(這裏保證了數據的完整性)。 至此,AB互有一對公私鑰,這樣就保證了信息都是對方加密的密文,別人看不了,也沒法修改。
可是有一個新的問題:假如擁有B公鑰的C公司偷換了A放在B公司的A的公鑰,換成本身的C的公鑰,而後模擬A發送信息,這樣同樣會讓B不知道是A發起的交易!
引入新的概念:數字證書。A的公鑰通過了公證,這就能夠保證B使用公鑰解開的數字簽名確定是A的數字簽名。
XSS和CSRF 1、XSS:跨站腳本攻擊,是一種網站應用程序的安全漏洞攻擊,是代碼注入的一種。常見方式是將惡意代碼注入合法代碼裏隱藏起來,再誘發惡意代碼,從而進行各類各樣的非法活動。 預防: 1、使用XSS Filter 輸入過濾,對用戶提交的數據進行有效性驗證,僅接受指定長度範圍內並符合咱們指望格式的的內容提交,阻止或者忽略除此外的其餘任何數據。 輸出轉義,當須要將一個字符串輸出到Web網頁時,同時又不肯定這個字符串中是否包括XSS特殊字符,
爲了確保輸出內容的完整性和正確性,輸出HTML屬性時可使用HTML轉義編碼(HTMLEncode)進行處理,輸出到<script>中,能夠進行JS編碼。 使用 HttpOnly Cookie 將重要的cookie標記爲httponly,這樣的話當瀏覽器向Web服務器發起請求的時就會帶上cookie字段,可是在js腳本中卻不能訪問這個cookie,
這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie。 2、CSRF:跨站請求僞造,也稱 XSRF,是一種挾制用戶在當前已登陸的Web應用程序上執行非本意的操做的攻擊方法。
與 XSS 相比,XSS利用的是用戶對指定網站的信任,CSRF利用的是網站對用戶網頁瀏覽器的信任。 //預防:用戶操做限制——驗證碼機制 方法:添加驗證碼來識別是否是用戶主動去發起這個請求,因爲必定強度的驗證碼機器沒法識別,所以危險網站不能僞造一個完整的請求。 優勢:簡單粗暴,低成本,可靠,能防範99.99%的攻擊者。 缺點:對用戶不友好。 請求來源限制——驗證 HTTP Referer 字段 //方法:在HTTP請求頭中有一個字段叫Referer,它記錄了請求的來源地址。 服務器須要作的是驗證這個來源地址是否合法,若是是來自一些不受信任的網站,則拒絕響應。 優勢:零成本,簡單易實現。 缺點:因爲這個方法嚴重依賴瀏覽器自身,所以安全性全看瀏覽器。 額外驗證機制——token的使用 //方法:使用token來代替驗證碼驗證。因爲黑客並不能拿到和看到cookie裏的內容,因此沒法僞造一個完整的請求。基本思路以下: 服務器隨機產生token(好比把cookie hash化生成),存在session中,放在cookie中或者以ajax的形式交給前端。 前端發請求的時候,解析cookie中的token,放到請求url裏或者請求頭中。 服務器驗證token,因爲黑客沒法獲得或者僞造token,因此能防範csrf
1、jsonp 儘管瀏覽器有同源策略,可是 <script> 標籤的 src 屬性不會被同源策略所約束,能夠獲取任意服務器上的腳本並執行。
jsonp 經過插入script標籤的方式來實現跨域,參數只能經過url傳入,僅能支持get請求。 實現原理: //Step1: 建立 callback 方法 //Step2: 插入 script 標籤 //Step3: 後臺接受到請求,解析前端傳過去的 callback 方法,返回該方法的調用,而且數據做爲參數傳入該方法 //Step4: 前端執行服務端返回的方法調用 下面代碼僅爲說明 jsonp 原理,項目中請使用成熟的庫。分別看一下前端和服務端的簡單實現: //前端代碼 function jsonp({url, params, cb}) { return new Promise((resolve, reject) => { //建立script標籤 let script = document.createElement('script'); //將回調函數掛在 window 上 window[cb] = function(data) { resolve(data); //代碼執行後,刪除插入的script標籤 document.body.removeChild(script); } //回調函數加在請求地址上 params = {...params, cb} //wb=b&cb=show let arrs = []; for(let key in params) { arrs.push(`${key}=${params[key]}`); } script.src = `${url}?${arrs.join('&')}`; document.body.appendChild(script); }); } //使用 function sayHi(data) { console.log(data); } jsonp({ url: 'http://localhost:3000/say', params: { //code }, cb: 'sayHi' }).then(data => { console.log(data); }); //express啓動一個後臺服務 let express = require('express'); let app = express(); app.get('/say', (req, res) => { let {cb} = req.query; //獲取傳來的callback函數名,cb是key res.send(`${cb}('Hello!')`); }); app.listen(3000);
2、jsonp 只能支持 get 請求,cors 能夠支持多種請求。cors 並不須要前端作什麼工做。 簡單跨域請求: 只要服務器設置的Access-Control-Allow-Origin Header和請求來源匹配,瀏覽器就容許跨域 請求的方法是get,head或者post。 Content-Type是application/x-www-form-urlencoded, multipart/form-data 或 text/plain中的一個值,或者不設置也能夠,通常默認就是application/x-www-form-urlencoded。 請求中沒有自定義的HTTP頭部,如x-token。(應該是這幾種頭部 Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type) //簡單跨域請求 app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'XXXX'); }); //帶預檢(Preflighted)的跨域請求 不滿於簡單跨域請求的,便是帶預檢的跨域請求。服務端須要設置 Access-Control-Allow-Origin (容許跨域資源請求的域) 、
Access-Control-Allow-Methods (容許的請求方法) 和 Access-Control-Allow-Headers (容許的請求頭) app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'XXX'); res.setHeader('Access-Control-Allow-Headers', 'XXX'); //容許返回的頭 res.setHeader('Access-Control-Allow-Methods', 'XXX');//容許使用put方法請求接口 res.setHeader('Access-Control-Max-Age', 6); //預檢的存活時間 if(req.method === "OPTIONS") { res.end(); //若是method是OPTIONS,不作處理 } });
3、nginx 反向代理 使用nginx反向代理實現跨域,只須要修改nginx的配置便可解決跨域問題。 A網站向B網站請求某個接口時,向B網站發送一個請求,nginx根據配置文件接收這個請求,代替A網站向B網站來請求。 nginx拿到這個資源後再返回給A網站,以此來解決了跨域問題。 例如nginx的端口號爲 8090,須要請求的服務器端口號爲 3000。(localhost:8090 請求 localhost:3000/say) nginx配置以下: server { listen 8090; server_name localhost; location / { root /Users/liuyan35/Test/Study/CORS/1-jsonp; index index.html index.htm; } location /say { rewrite ^/say/(.*)$ /$1 break; proxy_pass http://localhost:3000; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; } # others }
使用 HttpOnly Cookie
將重要的cookie標記爲httponly,這樣的話當瀏覽器向Web服務器發起請求的時就會帶上cookie字段,可是在js腳本中卻不能訪問這個cookie,
這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie。
保存用戶登陸狀態。例如將用戶id存儲於一個cookie內,這樣當用戶下次訪問該頁面時就不須要從新登陸了,如今不少論壇和社區都提供這樣的功能。
cookie還能夠設置過時時間,當超過期間期限後,cookie就會自動消失。所以,系統每每能夠提示用戶保持登陸狀態的時間:常見選項有一個月、三個 月、一年等。
XSS(跨站腳本攻擊)是指攻擊者在返回的HTML中嵌入javascript腳本,爲了減輕這些攻擊,須要在HTTP頭部配上,set-cookie: //httponly-這個屬性能夠防止XSS,它會禁止javascript腳原本訪問cookie。 //secure - 這個屬性告訴瀏覽器僅在請求爲https的時候發送cookie。
1、保存用戶登陸狀態。例如將用戶id存儲於一個cookie內,這樣當用戶下次訪問該頁面時就不須要從新登陸了,如今不少論壇和社區都提供這樣的功能。
cookie還能夠設置過時時間,當超過期間期限後,cookie就會自動消失。所以,系統每每能夠提示用戶保持登陸狀態的時間:常見選項有一個月、三個 月、一年等。 2、跟蹤用戶行爲。例如一個天氣預報網站,可以根據用戶選擇的地區顯示當地的天氣狀況。
若是每次都須要選擇所在地是煩瑣的,當利用了 cookie後就會顯得很人性化了,系統可以記住上一次訪問的地區,當下次再打開該頁面時,它就會自動顯示上次用戶所在地區的天氣狀況。
由於一切都是在後 臺完成,因此這樣的頁面就像爲某個用戶所定製的同樣,使用起來很是方便 三、定製頁面。若是網站提供了換膚或更換佈局的功能,那麼可使用cookie來記錄用戶的選項,例如:背景色、分辨率等。當用戶下次訪問時,仍然能夠保存上一次訪問的界面風格。
(function(){ var cookieObj = { //修改或是添加cookie 'add': function(name, value, hours) { var expire = ""; if(hours != null){ expire = new Date((new Date()).getTime() + hours * 3600000); expire = "; expires=" + expire.toGMTString(); } document.cookie = name + "=" + escape(value) + expire + ";path=/"; //若是指定域名可使用以下 //document.cookie = name + "=" + escape(value) + expire + ";path=/;domain=findme.wang"; }, //讀取cookie 'get': function(c_name){ if (document.cookie.length>0) { c_start = document.cookie.indexOf(c_name + "="); if (c_start != -1) { c_start=c_start + c_name.length+1; c_end=document.cookie.indexOf(";",c_start); if (c_end == -1) { c_end = document.cookie.length; } return unescape(document.cookie.substring(c_start,c_end)); } } return ""; } }; window.cookieObj=cookieObj; }());
共同點:都是保存在瀏覽器端,而且是同源的
Cookie:cookie數據始終在同源的http請求中攜帶(即便不須要),即cookie在瀏覽器和服務器間來回傳遞。
而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。
cookie數據還有路徑(path)的概念,能夠限制cookie只屬於某個路徑下,存儲的大小很小隻有4K左右。
(key:能夠在瀏覽器和服務器端來回傳遞,存儲容量小,只有大約4K左右)
sessionStorage:僅在當前瀏覽器窗口關閉前有效,天然也就不可能持久保持,localStorage:始終有效,窗口或瀏覽器關閉也一直保存,所以用做持久數據;
cookie只在設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉。
(key:自己就是一個回話過程,關閉瀏覽器後消失,session爲一個回話,當頁面不一樣即便是同一頁面打開兩次,也被視爲同一次回話)
localStorage:localStorage 在全部同源窗口中都是共享的;cookie也是在全部同源窗口中都是共享的。
(key:同源窗口都會共享,而且不會失效,無論窗口或者瀏覽器關閉與否都會始終生效)
Ajax請求過程:
1)客戶端產生js的事件
2)建立XMLHttpRequest對象
3)對XMLHttpRequest進行配置
4)經過AJAX引擎發送異步請求
5)服務器端接收請求而且處理請求,返回html或者xml內容
6)XML調用一個callback()處理響應回來的內容
7)頁面局部刷新 在javascript裏面寫AJax的時,最關鍵的一步是對XMLHttpRequest對象創建監聽,即便用「onreadystatechange」方法。
監聽的時候,要對XMLHttpRequest對象的請求狀態進行判斷,一般是判斷readyState的值爲4且http返回狀態status的值爲200或者304時執行咱們須要的操做。 readyState 屬性表示Ajax請求的當前狀態。
0 表明未初始化。 尚未調用 open 方法 1 表明正在加載。 open 方法已被調用,但 send 方法尚未被調用 2 表明已加載完畢。send 已被調用。請求已經開始 3 表明交互中。服務器正在發送響應 4 表明完成。響應發送完畢
2**開頭 (請求成功)表示成功處理了請求的狀態代碼。 200 (成功) 服務器已成功處理了請求。 一般,這表示服務器提供了請求的網頁。 201 (已建立) 請求成功而且服務器建立了新的資源。 202 (已接受) 服務器已接受請求,但還沒有處理。 203 (非受權信息) 服務器已成功處理了請求,但返回的信息可能來自另外一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部份內容) 服務器成功處理了部分 GET 請求。 3** 開頭 (請求被重定向)表示要完成請求,須要進一步操做。 一般,這些狀態代碼用來重定向。 300 (多種選擇) 針對請求,服務器可執行多種操做。 服務器可根據請求者 (user agent) 選擇一項操做,或提供操做列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。 303 (查看其餘位置) 請求者應當對不一樣的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 若是服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。
302和307的區別:
02是http1.0的協議狀態碼,在http1.1版本的時候爲了細化302狀態碼又出來了兩個303和307,nginx
你能夠理解爲303就是咱們以前的302乾的事情,臨時重定向。web
307有點意思:ajax
若是這不是一個GET或者HEAD請求,那麼瀏覽器禁止自動進行重定向,除非獲得用戶的確認,由於請求的條件可能所以發生變化算法
不是get或head,那好比咱們提交一個post會怎麼樣。express
**303重定向不會自動吧get,post的請求帶到目標url去。
307重定向會把post的請求自動帶到目標url,而對於get請求307也不會把參數帶過去**
4**開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。 400 (錯誤請求) 服務器不理解請求的語法。 401 (未受權) 請求要求身份驗證。 對於須要登陸的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 沒法使用請求的內容特性響應請求的網頁。 407 (須要代理受權) 此狀態代碼與 401(未受權)相似,但指定請求者應當受權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 若是請求的資源已永久刪除,服務器就會返回此響應。 411 (須要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未知足前提條件) 服務器未知足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器沒法處理請求,由於請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(一般爲網址)過長,服務器沒法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 若是頁面沒法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未知足指望值) 服務器未知足"指望"請求標頭字段的要求。 5**開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤多是服務器自己的錯誤,而不是請求出錯。 500 (服務器內部錯誤) 服務器遇到錯誤,沒法完成請求。 501 (還沒有實施) 服務器不具有完成請求的功能。 例如,服務器沒法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器做爲網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前沒法使用(因爲超載或停機維護)。 一般,這只是暫時狀態。 504 (網關超時) 服務器做爲網關或代理,可是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。
1.服務器首先產生Etag,服務器可在稍後使用它來判斷頁面是否被修改。本質上,客戶端經過該記號傳回服務器要求服務器驗證(客戶端)緩存) 2.304是HTTP的狀態碼,服務器用來標識這個文件沒有被修改,不返回內容,瀏覽器接受到這個狀態碼會去去找瀏覽器緩存的文件 3.流程:客戶端請求一個頁面A。服務器返回頁面A,並在A上加一個Tage客服端渲染該頁面,並把Tage也存儲在緩存中。
客戶端再次請求頁面A並將上次請求的資源和ETage一塊兒傳遞給服務器。服務器檢查Tage.而且判斷出該頁面自上次客戶端請求以後未被修改。直接返回304 last-modified: 客服端請求資源,同時有一個last-modified的屬性標記此文件在服務器最後修改的時間,客服端第二次請求此url時,根據http協議。
瀏覽器會向服務器發送一個If-Modified-Since報頭,詢問該事件以後文件是否被修改,沒修改返回304 //有了Last-Modified,爲何還要用ETag? 一、由於若是在一秒鐘以內對一個文件進行兩次更改,Last-Modified就會不正確(Last—Modified不能識別秒單位的修改) 2、某些服務器不能精確的獲得文件的最後修改時間 3、一些文件也行會週期新的更改,可是他的內容並不改變(僅僅改變修改的事件),這個時候咱們並不但願客戶端認爲文件被修改,而從新Get //ETag,爲何還要用Last-Modified? 1、二者互補,ETag的判斷的缺陷,好比一些圖片等靜態文件的修改 2、若是每次掃描內容都生成ETag比較,顯然要比直接比較修改時間慢的多。 //ETag是被請求變量的實體值(文件的索引節,大小和最後修改的時間的Hash值) 一、ETag的值服務器端對文件的索引節,大小和最後的修改的事件進行Hash後獲得的。
//(1)400狀態碼:請求無效
產生緣由:
前端提交數據的字段名稱和字段類型與後臺的實體沒有保持一致
前端提交到後臺的數據應該是json字符串類型,可是前端沒有將對象JSON.stringify轉化成字符串。
解決方法:
對照字段的名稱,保持一致性
將obj對象經過JSON.stringify實現序列化
//(2)401狀態碼:當前請求須要用戶驗證
//(3)403狀態碼:服務器已經獲得請求,可是拒絕執行
第一步:將載入的HTML文件解析成DOM樹(DOM Tree),而且將各個標記標識解析成DOM樹的各個節點;
在解析HTML的同時會將CSS樣式解析成CSS規則(CSS Rules)。
第二步:將解析成的DOM樹和CSS規則進行關聯生成渲染樹(Render Tree)。
第三步:進入佈局階段,爲DOM樹的每一個節點分配在屏幕上出現的確切座標(這一階段仍是渲染樹)
第四步:進入繪製階段,在這裏渲染引擎的工做就結束了,接下來就給用戶界面後端(UI Backend)對渲染樹的每一個節點進行繪製,呈現出頁面效果。
輸入URL以後的瀏覽器的解析過程詳細說一下
1、瀏覽器地址欄輸入url 二、瀏覽器會先查看瀏覽器緩存--系統緩存--路由緩存,若有存在緩存,就直接顯示。若是沒有,接着第三步 3、域名解析(DNS)獲取相應的ip 4、瀏覽器向服務器發起tcp鏈接,與瀏覽器創建tcp三次握手 5、握手成功,瀏覽器向服務器發送http請求,請求數據包 6、服務器請求數據,將數據返回到瀏覽器 7、瀏覽器接收響應,讀取頁面內容,解析html源碼,生成DOm樹 八、解析css樣式、瀏覽器渲染,js交互綁定多個域名,數量不限;
當咱們在瀏覽器中輸入一個URL,例如」www.google.com」時,這個地址並非谷歌網站真正意義上的地址。
互聯網上每一臺計算機的惟一標識是它的IP地址,所以咱們輸入的網址首先須要先解析爲IP地址,這一過程叫作DNS解析。
DNS解析是一個遞歸查詢的過程。例如,咱們須要解析」www.google.com」時,會經歷如下步驟:
原理:當瀏覽器再次訪問一個已經訪問過的資源時,它會這樣作: 看看是否命中強緩存,若是命中,就直接使用緩存了。 若是沒有命中強緩存,就發請求到服務器檢查是否命中協商緩存。 若是命中協商緩存,服務器會返回 304 告訴瀏覽器使用本地緩存。 不然,返回最新的資源。
瀏覽器緩存分爲強緩存和協商緩存。當客戶端請求某個資源時,獲取緩存的流程以下:
http header
判斷它是否命中強緩存,若是命中,則直接從本地獲取緩存資源,不會發請求到服務器;request header
驗證這個資源是否命中協商緩存,稱爲http
再驗證,若是命中,服務器將請求返回,但不返回資源,而是告訴客戶端直接從緩存中獲取,客戶端收到返回後就會從緩存中獲取資源;ctrl+f5
強制刷新網頁時,直接從服務器加載,跳過強緩存和協商緩存;f5
刷新網頁時,跳過強緩存,可是會檢查協商緩存;http1.0
時的規範,值爲一個絕對時間的 GMT
格式的時間字符串,表明緩存資源的過時時間)http1.1
的規範,強緩存利用其 max-age
值來判斷緩存資源的最大生命週期,它的值單位爲秒)協商緩存 Last-Modified(值爲資源最後更新時間,隨服務器response返回) If-Modified-Since(經過比較兩個時間來判斷資源在兩次請求期間是否有過修改,若是沒有修改,則命中協商緩存) ETag(表示資源內容的惟一標識,隨服務器response返回) If-None-Match(服務器經過比較請求頭部的If-None-Match與當前資源的ETag是否一致來判斷資源是否在兩次請求之間有過修改,若是沒有修改,則命中協商緩存)
//reflow(迴流) reflow翻譯爲迴流,指的是頁面再次構建render樹。每一個頁面至少發生一次迴流,就是第一次加載頁面的時候 此外,當頁面中有任何改變可能形成文檔結構發生改變(即元素間的相對或絕對位置改變),都會發生reflow,常見的有: 添加或刪除元素(opacity:0除外,它不是刪除) 改變某個元素的尺寸或位置 瀏覽器窗口改變(resize事件觸發) //repaint(重繪) repaint翻譯爲重繪,它能夠類比爲上面的第四步,根據render樹繪製頁面,它的性能損耗比迴流要小。每次迴流必定會發生重繪。
此外,如下操做(不影響文檔結構的操做,影響結構的會發生迴流)也會發生重繪: 元素的顏色、透明度改變 text-align等
部分渲染樹(或者整個渲染樹)須要從新分析而且節點尺寸須要從新計算。這被稱爲重排。注意這裏至少會有一次重排-初始化頁面佈局。
因爲節點的幾何屬性發生改變或者因爲樣式發生改變,例如改變元素背景色時,屏幕上的部份內容須要更新。這樣的更新被稱爲重繪。
DOM
節點display: none
隱藏一個 DOM
節點-觸發重排和重繪visibility: hidden
隱藏一個 DOM
節點-只觸發重繪,由於沒有幾何變化DOM
節點添加動畫
在早期的HTTP/1.0中,每次http請求都要建立一個鏈接,而建立鏈接的過程須要消耗資源和時間,爲了減小資源消耗,縮短響應時間,就須要重用鏈接。
在後來的HTTP/1.0中以及HTTP/1.1中,引入了重用鏈接的機制,就是在http請求頭中加入Connection: keep-alive來告訴對方這個請求響應完成後不要關閉,下一次我們還用這個請求繼續交流。
協議規定HTTP/1.0若是想要保持長鏈接,須要在請求頭中加上Connection: keep-alive。 keep-alive的優勢: 較少的CPU和內存的使用(因爲同時打開的鏈接的減小了) 容許請求和應答的HTTP管線化 下降擁塞控制 (TCP鏈接減小了) 減小了後續請求的延遲(無需再進行握手) 報告錯誤無需關閉TCP連