關於全棧工程師的貼士

全棧工程師應該具備的技術

前端

  • html(5)+css(3)
  • JavaScript(jQuery,vue,react…)

後端

  • Java(jsp)
  • Python
  • Node
  • PHP(php)
  • C#(.net->dot net)(ASP.NET)
  • C

數據庫

  • MySQL
  • SqlServer
  • oracle
  • MongoDB(和node結合緊密)

自動化

  • git/svn
  • webpack(基於node運行的)
  • 服務器部署工具iis/apache/nginx

客戶端和服務器端怎樣通信

面試題:當在瀏覽器地址欄輸入地址,如:https://www.baidu.com,點擊enter鍵後,獲取百度首頁面的這個過程都經歷了什麼?

** request瀏覽器請求階段 **
1. 首先根據客戶端輸入的域名,到DNS服務器上進行反解析(通過域名找到對應服務器的外網IP)(域名解析==DNS解析,DNS服務器是進行域名(domain name)和與之相對應的IP地址 (IP address)轉換的服務器)
2. 通過找到的外網IP,找到對應的服務器
3. 通過在地址欄中輸入的端口號(沒輸入時因爲不同協議有自己默認端口號)找到服務器上發佈的對應的項目
** response服務器響應階段 **
4. 服務器獲取到請求資源文件的地址,例如:news/product.html,把文件中的源代碼找到
5. 服務器端會把找到的雲代碼返回給客戶端(通過HTTP等協議返回)
** 瀏覽器自主渲染 **
6. 客戶端接收到源代碼後,會交給瀏覽器的內核(渲染引擎)進行渲染,最後由瀏覽器繪製出對應的頁面

HTTP

  • URI:統一資源標識符
  • URL:統一資源定位符
  • URN:統一資源名稱
  • URI=URL+URN

一個完整的URL組成

http://www.baidu.com/news/product.html?name=test&age=9#good

第一部分:傳輸協議

傳輸協議是用來完成客戶端和服務端的數據(內容)的,類似於快遞小哥。

  1. 客戶端不僅可以向服務器發送請求,還可以把一些內容傳遞給服務器
  2. 服務器端也可以把內容返回給客戶端
  3. 客戶端和服務器端傳輸的內容總稱爲HTTP報文 ,這些報文信息都是基於傳輸協議完成傳輸的,客戶端傳遞給服務器叫做請求(request),服務器返回給客戶端叫做響應(response),request+response兩個階段統稱爲一個HTTP事務(事務:一件完整的事情)。

HTTP事務

  1. 當客戶端向服務器端發送請求,此時客戶端和服務端會建立一個傳輸通道(連接通道),傳輸協議就是基於這個通道把信息進行傳輸的
  2. 當服務端接收到請求信息,把內容返回個客戶端後,傳輸通道會自動銷燬關閉

傳輸協議分類

  1. HTTP:超文本傳輸協議(客戶端和服務端傳輸的內容除了文本以外,還可以傳輸圖片、音視頻等文件流[二進制編碼/base64碼]),以及傳輸xml格式的數據等),是目前市場上應用最廣泛的傳輸協議
  2. HTTPS:HTTP+SSL,它比HTTP更加安全,因爲數據內容的傳輸通道是經過SSL加密的(它需要在服務器端進行特殊的處理),所以涉及資金類的網站一般都是HTTPS協議的。
  3. FTP:資源文件傳輸協議,一般用於客戶端把資源文件(不是代碼)上傳到服務器端,貨值從服務器端下載一些資源文件(一般ftp傳輸的內容會比HTTP這類協議傳輸的內容多)。

HTTP報文

  1. 起始行
    請求起始行
    相應起始行
  2. 首部(頭部)
    請求頭:內置請求頭、自定義請求頭
    響應頭:內置響應頭、自定義響應頭
    通用頭:請求和響應都有
  3. 主體
    請求主體
    響應主體

請求XXX都是客戶端設置的信息,服務器端獲取這些信息
響應XXX都是服務器端設置的信息,客戶端用來接收這些信息

總結:

  • 客戶端傳遞給服務器端數據
  1. URL問號傳遞參數
  2. 設置請求頭
  3. 設置請求主體
  • 服務端返回給客戶端內容
  1. 設置響應頭(例如服務器時間)
  2. 設置響應主體

第二部分:域名

設置域名其實就是給不好記憶的服務去外網IP設置了一個好記憶的名字
頂級域名(一級域名):qq.com
二級域名:www.qq.comv.qq.com
三級域名:kbs.sports.qq.com

第三部分:端口號

在服務器發佈項目的時候,,我們可以通過端口號區分當前服務器上不同的項目
一臺服務器的端口號取值範圍:0~65535之間。如果電腦上安裝了很多程序,有一些渡口號是被佔用了
HTTP:默認端口號80
HTTPS:默認端口號443
FTP:默認端口號21
對於上述是三個端口號其實是很重要的,如果被其他程序佔用,則我們不能使用。所以服務器上一般禁止安裝其他程序的

第四部分:請求資源文件的路徑名稱

在服務器中發佈項目的時候,我們一般會配置一些默認文檔:用戶即使不輸入請求文件的名稱,服務器也會找到默認文檔(一般默認文檔都是index/default)
我們通常爲了做SEO優化,會把一些動態頁面的地址(xxx.php、xxx.asp)進行僞URL重寫(需要服務器處理)
https://item.jd.com/4325427.html
不可能是有一個商品自己就單獨些一個詳情頁,肯定是同一個詳情頁做的不同處理
1)第一種方案:
由後臺語言根據詳情頁模板動態生成具體的詳情頁面
2)第二種方案:
當前頁面就是一個頁面,例如:detail.html/detail.php,我們做詳情頁面的時候,開發是按照detail.html?id=4325427來開發的,但是這種頁面不方便做SEO優化,此時我們把真實的地址進行重寫,重寫爲我們看到的4325427.html

第五部分:問號傳參

?name=test&age=9
把一些值通過xxx=xxx的方式,放在一個URL的末尾,通過問號傳遞
[作用]
1)在AJAX請求中,我們可以通過問號傳遞參數的方式,客戶端把一些信息傳遞給服務器,服務器根據傳遞信息的不一樣返回不同的數據

//$.ajax(url,{});
//$.get(url,function(){});對於AJAX請求的特殊寫法,原理還是基於AJAX方法實現的 $.post/$.script
$.ajax({
	url:'getInfo?id=12'
});
//當前案例:我們傳遞給服務器的編號是多少,服務器端就會把對應編號人員信息給返回

2)消除AJAX請求中GET方式緩存

$.ajax({
	url:'xxx?_=1122',
	method:'get
})
//我們會在請求URL的末尾追加一個隨機數_=隨機數,保證每一次請求的URL都是不一樣的,以此來消除GET請求遺留的緩存問題

3)通過URL傳參傳遞參數的方式,可以實現頁面之間信息的通信。例如:我們有兩個頁面A/B,A是列表頁面,B是詳情頁,點擊A中的某一條信息,進入到唯一的詳情頁B,如何展示不同的信息,這種操作就可以基於URL問號傳遞參數來實現了

第六部分:HASH值

#xxx
URL末尾傳遞的井號什麼,就是HASH值(哈希值)
[作用]
1)頁面中錨點定位
2)前端路由(SPA單頁面開發)

web前端開發常用的優化技巧彙總

減少http請求次數或請求數據的大小

頁面中每發送一次HTTP請求,都需要完成請求+響應的完整HTTP事務,會消耗一些時間,也可能會導致HTTP連接通道堵塞,爲了提高頁面加載速度和運行的性能,我們應該減少HTTP請求的次數和請求數據的大小

  1. 採用CSS雪碧圖(CSS Sprit/CSS圖片精靈)技術,把一些小圖合併在一張大圖上,使用的時候通過背景圖片定位,定位到具體的某一張小圖上
  2. 真實項目中,我們最好把CSS或者JS文件合併壓縮。尤其是在移動端開發的時候,如果CSS或者JS內容不是很多,我們可以採用內嵌式,以此減少HTTP請求的次數,加快頁面加載速度
    1)CSS合併成一個,JS最好合併成一個
    2)首先通過一些工具(例如:webpack)把合併後的CSS或者JS壓縮成xxx.min.js,減少文件大小
    3)服務器端開啓資源文件的GZIP壓縮
    4) 通過一些自動化工具完成CSS以及JS的合併壓縮,或者再完成LESS轉CSS,ES6轉ES5等操作,我們把這中自動化構建模式,稱之爲前端“工程化”開發
  3. 採用圖片懶加載技術,在頁面開始加載的時候,不請求真實的圖片地址,而是用默認圖佔位,當頁面加載完成後,再根據相關的條件依次加載真實的圖片(減少頁面首次加載HTTP請求的次數)
    真實項目中,我們開始圖片都不加載,頁面首次加載完成,先把第一屏幕中可以看到的圖片進行加載,隨着頁面滾動,再把下面區域中能夠呈現出來的圖片進行加載
    根據圖片懶加載技術,我們還可以進行擴充,數據的懶加載
    1)開始加載頁面的時候,我們只把首屏或者前兩屏的數據從服務器端進行請求(有些網站首屏數據是後臺渲染好,整體返回飛客戶端呈現)
    2)當頁面下拉,滾動到那個區域,再把這個區域需要的數據進行請求(請求回來做數據綁定以及圖片延遲加載等)
    3)分頁展示技術採用的也是數據的懶加載思想實現的:如果我們請求的數據是很多的數據,我們最好分批請求,開始只請求第一頁的數據,當用戶點擊第二頁(微博是下拉到一定距離後,再請求第二頁數據)的時候在請求第二頁數據
  4. 對於不經常更新的數據,最好採用瀏覽器的304緩存做處理(主要由服務器處理)
    例如:第一次請求CSS和JS下來,瀏覽器會把請求的內容緩存起來,如果做了304處理用戶再次請求css和js,只接從緩存中讀取,不需要再去服務器獲取(減少HTTP請求次數)
    當用戶強制刷新頁面(CTRL+F5)或者當前緩存的css或js發生了變動,都會重新從服務器拉取
    對於客戶端來講,我們還可以基於localStorage來做一些本地存儲,例如:第一次請求的數據或者不經常更新的css和js,我們都可以把內容存儲在本地,下一次頁面加載,我們從本地中獲取即可,我們設定一定期限或者一些標識,可以控制在某個階段重新從服務器獲取
  5. 使用字體圖標代替一些頁面中的位圖(圖片),這樣不僅做適配的時候方便,更加輕量級,而且減少HTTP請求次數(類似於雪碧圖)
  6. 如果當前頁面中出此案audio或者video標籤時,我們最好設置他們的preload=none;頁面加載的時候,音視頻資源不進行加載,播放的時候再加載(減少頁面首次加載HTTP請求的次數)
    preload=auto:頁面首次加載的時候就把音視頻資源進行加載
    prelooad=metadata:頁面首次加載的時候只把音視頻資源的頭部信息進行加載
  7. 在客戶端和服務器端進行數據通信的時候,我們儘量採用JSON格式進行數據傳輸
    1) JSON格式的數據,能夠清晰明瞭的展示出數據結構,而且也方便我們自己獲取和操作
    2)相對於很早以前的XML格式傳輸,JSON格式的數據更加輕量級
    3)客戶端和服務器端都支持JSON格式數據的處理,處理起來非常方便
    4)真實項目中,並不是所有的數據都要基於JSON,我們儘可能這樣子,但是對於某些特殊需求(例如:文件流傳輸或文檔傳輸),使用JSON就不合適了
  8. 採用CDN加速
    CDN:分佈式(地域分佈式)

關於編寫代碼時候的一些優化技巧

除了減少HTTP請求次數和大小可以優化性能,我們在編寫代碼的時候,也可以進行一些優化,讓頁面的性能有所提升(有刺些不好的代碼編寫習慣會導致頁面性能消耗太大,例如:內存泄漏)

  1. 在編寫JS代碼的時候,儘量減少對DOM的操作
    在JS中操作DOM是一個非常消耗性能的事情,但是我們又不可避免的操作DOM,我們只能儘量減少對於他的操作
    [操作DOM的弊端]
    1)DOM存在映射機制(JS中的DOM元素對象和頁面中的DOM結構是存在映射機制的,一改則都改),這種映射機制是瀏覽器按照W3C標準完成對JS語言的構建和DOM的構建(其實就是構建了一個監聽機制),操作DOM是同時要修改兩個地方,相對於一些其他JS編程來說是消耗性能的
    2)頁面中的DOM結構改變或者樣式改變,會觸發瀏覽器的迴流(瀏覽器會把DOM結構重新進行計算,這個操作很耗性能)
    重繪(把一個元素的樣式重新渲染)。、
  2. 編寫代碼的時候,更多的使用異步編程
    同步編程會導致:上面東西完不成,下面任務也做不了,我們開發的時候,可以把某一個區域模塊都設置爲異步編程,這樣只要模塊之間沒有必然的先後順序,都可以獨立進行加載,不會受到上面模塊的堵塞影響(用的不多)
    尤其是AJAX數據請求,我們一般都要使用異步編程,最好是基於promise設計模式進行管理(項目中經常使用fetchvue axios等插插件進行AJA 請求處理,因爲這些插件中就是基於promise設計模式對AJAX進行的封裝處理)
  3. 在真實項目中,我們 儘可能避免一次性循環過多數據(因爲循環操作是同步便編程)尤其是要避免while導致的死循環操作
  4. css選擇器優化
    1)儘量減少標籤選擇器的使用
    2)儘可能少使用 ID選擇器,多使用樣式累選擇器(通用性強)
    3)減少選擇器前面的前綴,例如:.headerBox ,nav .left a{}(選擇器是從右向左查找的)
  5. 避免使用CSS表達式
/*css表達式*/
.box{
  background-color:expression((new Date()).getHours()%2?'red':'blue')
   
}
  1. 減少頁面中的冗餘代碼,儘可能提高方法的重複使用率:“低耦合高內聚”
  2. 最好css放在head中,js放在body尾部,讓頁面加載的時候,先加載css,再加載js(先呈現頁面,再給用戶提供操作)
  3. js中避免使用eval
    1)性能消耗大
    2)代碼壓縮後,容易出現代碼執行錯亂問題
  4. js中儘量減少閉包的使用
    1)閉包會形成一個不銷燬的棧內存,過多的棧內存累計會影響頁面的性能
    2)容易導致內存泄漏
    閉包也有自己的優勢:保存和保護,我們只能儘量減少,但是無可避免
  5. 在做DOM事件綁定的時候,儘量避免一個個的事件綁定,而是採用性能更高的事件委託(事件代理)來實現
    把事件綁定給外層容器,當裏面的後代元素相關行爲被觸發,外層容器綁定的方法也會被觸發執行(冒泡傳播機制導致),通過事件源是誰,我們做不同的操作即可
  6. 儘量使用CSS3動畫代替JS動畫,因爲CSS3的動畫或者變形都開啓了硬件加速,性能比JS動畫好
  7. 編寫JS代碼的時候儘可能使用設計模式來構建體系,方便後期的維護,也提高了擴充性
  8. css中減少對濾鏡的使用,頁面中也減少對於flash的使用

關於頁面的SEO優化技巧

  1. 頁面中杜絕出現死鏈接(404頁面),而且對於用戶輸入一個錯誤頁面,我們要引導到404提示頁面中(服務器處理的)
  2. 避免瀏覽器中異常錯誤的拋出
    1)儘可能避免代碼出錯
    2)使用TRY CATCH做異常信息捕獲
  3. 增加頁面關鍵詞優化

AJAX基礎知識及核心原理解讀

AJAX基礎知識

什麼是AJAX
async javascript and xml,異步的js和xml

xml:可擴展標記語言
作用是用來存儲數據的(通過自己擴展的標記名稱清晰的展示出數據結構)
ajax之所以稱爲異步的js和xml,主要原因是:當初最開始用ajax實現客戶端和服務端數據通信的時候,傳輸的數據格式一般都是xml格式的數據,我們把它稱之爲異步的js和xml(現在一般都是基於json格式進行數據傳輸的)

異步的js
這裏的異步不是說ajax只能基於異步進行請求(雖然建議都是使用異步編程的),這裏的異步特指的是局部刷新

局部刷新VS全局刷新

非完全前後點分離項目中,前段開發只需要完成頁面的製作,並且把一些基礎的人機交互效果使用js完成即可,頁面中需要動態呈現內容的部分都是後臺開發工程師做數據綁定和基於服務器進行渲染的(服務器端渲染)
[優勢]
1) 動態展示的數據在頁面的源代碼中可以看見,有利於SEO優化推廣(有利於搜索引擎的收錄和抓取)
2) 從服務器端獲取的結果就已經是最後要呈現的結果了,不需要客戶端做額外的事情,所以頁面加載速度快(前提是服務器端處理的速度足夠快),所以類似於京東、淘寶這些網站,首屏數據一般是經由服務器端渲染的
[弊端]
1)如果頁面中存在需要實時更新的數據,每一次想要展示最新的數據,頁面都要重新的刷星一次,這樣肯定不行
2) 都交給服務器端做數據渲染,服務器端的壓力太大,若干服務器處理不過來,頁面呈現的速度更慢(所以京東淘寶這類網站,除了首屏是服務器端渲染的,其他屏一般都是客戶端做數據渲染綁定)
3) 這種模式不利於開發(開發效率低)

目前市場上大部分項目都是前後端完全分離的項目(也有非完全前後端分離的)
前後端完全分離的項目,頁面中需要動態綁定的數據交給客戶端完成渲染的
1) 把服務器端發送AJAX請求
2)把從服務器端獲取的數據解析處理,拼接成爲我們需要展示的HTML字符串
3)把拼接號的字符串替換頁面中某一部分的內容(局部刷新),頁面整體不需要重新加載,局部刷新即可
[優勢]
1)我們可以根據需求任意修改頁面中某一部分的內容改變(例如實時刷新即可),整體頁面不刷新,性能好,體驗號(所有表單驗證,需要實時刷新的等需求都要基於AJAX實現)
2)有利於開發,提高開發效率
a)前後端的完全分離,後臺不需要考慮前端如何實現,前端你也不需要後臺用 什麼技術,真正意義上實現了技術的劃分
b)可以同時進行開發:項目開發開始,首先制定前後端交互的接口文檔(文檔中包含了,調取哪個接口或者那些數據等協議規範),後臺把接口先寫好(目前很多公司也需要前端自己拿NODE來模擬這些接口),客戶端按照接口調取即可,後臺再次去實現接口功能即可
[弊端]
1.不利於SEO優化,第一次從服務器端獲取的內容不包含需要動態綁定的數據,所以頁面的源代碼中沒有這些內容,不利於SEO收錄,後期通過JS添加到頁面中的內容並不會寫在頁面的源代碼中
2.交由客戶端渲染,首先需要把頁面呈現,然後再通過JS的異步AJAX請求獲取數據,然後數據綁定,然後數據綁定,瀏覽器再把動態增加的部分重新渲染,無形中浪費了一些時間,沒有服務器端渲染頁面呈現速度快

基於原生JS實現AJAX

//創建一個AJAX對象
let xhr=new XMLHttpRequest();//不兼容IE6以及更低版本瀏覽器(IE6:ASctiveXObject)
//打開請求地址(可以理解爲一些基礎配置,但是並沒有發送請求)
xhr.open([method],[url],[async],[user name],[userr password]);
//監聽AJAX狀態改變,獲取響應信息(獲取響應頭信息、獲取響應主體信息)
xhr.onreadystatechange=()=>{
	if(xhr.readyState===4&&xhr.status===200){
		let result=xhr.responseText;//獲取響應主體中的內容
	}
}
//發送AJAX請求(括號中傳遞的內容就是請求主體的內容)
xhr.send(null);

分析第二步中細節點

xhr.open([method],[url],[async],[user name],[userr password]);
AJAX請求方式
共8種:get,post,put,head.delete,options,trace,connect
1、GET系列請求(獲取)

  • get
  • delete:從服務器上刪除某些資源文件
  • -head:只想獲取服務器返回的響應頭信息(響應主題內容不需要獲取)

  • 2、POST系列請求(推送)
  • post
  • put:向服務器中增加制定的資源文件

不管是哪一種請求方式,客戶端都可以把信息傳遞給服務器,服務器也可以把信息返回給客戶端,知識GET系列一般以獲取爲主(給的少,拿回來的多),而POST系列一般以推送爲主(給的多,拿回來的少)
1)我們想獲取一些動態展示的信息,一般使用GET請求,因爲只需要向服務器發送請求,告訴服務器端我們想要什麼,服務器端就會把需要的數據返回
2)在實現註冊功能的時候,我們需要把客戶輸入的信息發送給服務器進行存儲,服務器一般返回的是成功還是失敗等狀態,此時我們一般都是基於POST請求完成

** GET系列請求和POST系列請求,在項目實戰中存在很多的區別 **
1、GET請求傳遞給服務器的內容一般沒有POST請求傳遞給服務器的內容多
原因:GET請求傳遞給服務器內容一般都是基於URL地址問號傳遞參數來實現的,而POST請求一般是基於設置請求主體來實現的。
各瀏覽器都有自己關於URL最大長度限制(谷歌:8KB,火狐:7KB,IE:2KB),超過限制長度的部分,瀏覽器會自動截取掉,導致傳遞給服務器的數據缺失
理論上POST請求通過請求主體傳遞是沒有大小限制的,真實項目中爲了保證傳輸的速度,,我們也會限制大小(例如:上傳的資料或者圖片我們會做大小的限制)
2、GET請求很容易出現緩存(這個緩存不可控:一般我們都不需要),而POST不會出現緩存(除非自己做特殊處理)
原因:GET是通過URL問號傳參傳遞給服務器信息,而POST是設置請求主體。
設置請求主體不會出現緩存,但是URL傳遞參數就會出現緩存

//每隔一分鐘重新請求服務器端最新的數據,然後展示在頁面中(頁面中某些數據實時刷新)
setTimeout(()=>{
	$.ajax({
		url:'getList?lx=news',
		...
		success:result=>{
			//第一次請求數據回來,間隔一分鐘後,瀏覽器又發送一次請求,但是新發送的請求不管是地址還是傳遞參數都和第一次一樣,
			//瀏覽器很有可能會把上一次數據獲取,而不是獲取最新的數據
		}
	})
},60000);
//解決方案:每一次重新請求的時候,在URL的末尾追加一個隨機數,保證每一次請求的地址不完全一致,就可以避免是從緩存中讀取的數據
setTimeout(()=>{
	$.ajax({
		url:'getList?lx=news&_='+Math.random(),
		...
		success:result=>{
		
		}
	})
},60000);

3、GET請求沒有POST請求安全(POST也並不是十分安全,只是相對安全)
原因:還是因爲GET是URL傳參給服務器
有一種比較簡單的黑客技術:URL劫持,也就是可以把客戶端傳遞給服務器的數據劫持掉,導致信息泄露。

URL:請求數據的地址(API地址)
真實項目中,後臺開發工程師會編寫一個API文檔,在API文檔中彙總了獲取哪些數據需要使用哪些地址,我們按照文檔操作即可

ASYNC:異步(SYNC同步)
設置當前AJAX請求是異步還是同步的,不寫默認是異步(TRUE),如果設置爲FALSE,則代表當前請求是同步的

用戶名和密碼
這兩個參數一般不用,如果你請求的URL地址所在的服務器設定了訪問權限,則需要我們提供可同行的用戶名和密碼纔可以(一般服務器都是可以允許匿名訪問的)

第三部分細節分析

//監聽AJAX狀態改變,獲取響應信息(獲取響應頭信息、獲取響應主體信息)
xhr.onreadystatechange=()=>{
	if(xhr.readyState===4&&xhr.status===200){
		let result=xhr.responseText;//獲取響應主體中的內容
	}
}

AJAX狀態碼:描述當前AJAX操作的狀態的
xhr.readyState:包括五種
0:UNSEND 未發送,只要創建一個AJAX對象,默認值爲零
1:OPENED 我們已經執行了xhr.open這個操作
2:HEADERS_RECEVED 當前AJAX的請求已經發送,並且已經接收到服務器端返回的響應頭信息
3:LOADING 響應主體內容正在返回的路上
4:DONE 響應主體內容已經返回到客戶端

HTTP網絡狀態碼:記錄了當前服務器返回信息的狀態
xhr.status
200:成功,一個完整的HTTP事務完成(以2開頭的狀態碼一般都是成功)

以3開頭一般也是成功,只不過服務器端做了很多特殊的處理
301:Moved Permanently 永久轉移(永久重定向),一般應用於域名遷移
302:Move temporarily 臨時轉移(臨時重定向,新的HTTP版本中任務307是臨時重定向),一般用於服務器的負載均衡,當前服務器處理不了,我把當前請求臨時交給其他的服務器處理(一般圖片請求經常出現302,很多公司都有單獨的圖片服務器)
304:Not Modified 從瀏覽器緩存中獲取數據,把一些不經常更新的文件或者內容緩存到瀏覽器中,下一次從緩存中獲取,減輕服務器壓力,也提高頁面加載速度

以4開頭的,一般都是失敗,而且客戶端的問題偏大
400:請求參數錯誤
401:無權限訪問
404:訪問路徑不存在

以5開頭的,一般都是失敗,而且服務器的問題偏大
500:Internal Server Error 未知的服務器錯誤
503:Service Unavailable 服務器出超負載

AJAX中其他常用的屬性和方法

面試題:AJAX中總共支持幾個方法?
let xhr=new XMLHttpRequest();
console.dir(xhr);
[屬性]

  • readyState:存儲的是當前AJAX的狀態碼
  • response/responseText/responseXML:都是用來接收服務器返回的響應主體中的內容,只是根軍服務器返回內容的格式不一樣,我們使用不同的屬性接收即可
    • responseText:是最常用的,接收到的結果是字符串格式的(一般服務器返回的數據都是JSON格式字符串)
    • reseponseXML:偶爾用到,如果服務器端返回的是XML文檔數據,我們需要使用這個屬性接收
    • status:記錄了服務器端返回的HTTP狀態碼
    • statusText:對返回狀態碼的描述
    • timeout:設置當前AJAX請求的超時時間,假設我們設置時間爲3000ms,從AJAX請求發送開始,3秒後相應主體內容還沒有返回,瀏覽器會把當前AJAX請求任務輕質斷開

[方法]

  • abort():強制中斷AJAX請求
  • getAllResponseHeaders():獲取全部的響應頭信息(獲取的結果是一堆字符串文本)
  • getResponseHeaders(key):獲取指定屬性名的響應頭信息,例如:getResponseHeaders(‘date’)獲取響應頭中存儲的服務器的時間
  • open():打開一個URL地址
  • overrideMimeType():重寫數據的MIME類型
  • send():發送AJAX請求(括號中書寫的內容是客戶端基於請求主體把信息傳遞給服務器)
  • sendRequestHeader(key,value):設置請求頭信息(可以是設置的自定義請求頭信息)

[事件]

  • onabort:當AJAX被中斷請求觸發這個事件
  • onreadystatechange:AJAX狀態發生改變,會觸發這個事件
  • ontimeout:當AJAX請求超時時,會觸發這個事件

例子:

let xhr=new XMLHttpRequest();
xhr.open('get','temp.xml?_='+Math.random(),true);
//設置的請求頭 內容不是一個有效的值(請求頭部的內容不得出現中文漢字)
//設置請求頭信息必須在OPEN之後和SEND之前
xhr.setRequestHeader('aaa','xxx');
xhr.timeout=5000;
xhr.ontimeout=()=>{
    console.log('當前請求已經超時');
    xhr.abort();
};
xhr.onreadystatechange=()=>{
    let {readyState:state,status}=xhr;
    //說明請求數據成功了
    if(!/^(2|3)\d{2}$/.test(status)) return;
    //在狀態爲2時就可以獲取響應頭信息
    if(state==2){
        let headerAll=xhr.getAllResponseHeaders(),
            serverDate=xhr.getResponseHeader('date');
        console.log(headerAll,new Date(serverDate));//獲取的服務器時間是格林尼治時間(相比於北京時間差了8小時),通過new Date可以裝換爲北京時間

        //在狀態爲4的時候響應主體內容就已經回來了
        if(state===4){
            let valueText=xhr.responseText,
                valueXML=xhr.responseXML;
            console.log(valueText,valueXML)
        }
    }
};
xhr.send('name=mary&age=12');

JS中常用的編碼解碼方法

正常的編碼解碼(非加密)
1、escape/unescape:主要就是把中文漢字進行編碼和解碼的(一般只有js語言支持,也經常應用於前端頁面通信時候的中文漢字編碼)
2、encodeURI/decodeURI:基本上所有的編程語言都支持
3、encodeURIComponent/decodeURIComponent:和第二種方式非常的類似,區別在於

需求:我們URL問號傳遞參數的時候,我們傳遞的參數值還是一個URL或者包含很多特殊的字符,此時爲了不影響主要的URL,我們需要把傳遞的參數值進行編碼,使用encodeURI不能編碼一些特殊字符,所以只能使用encodeURIComponent處理

let str='http://www.baidu.com/?',
	obj={
		name:'小明',
		age:10,
		url:'http://www.qq.com/?lx=1'
	};
//把obj中的每一項屬性名和屬性值拼接到URL的末尾(問號傳參方式)
for(let key in obj){
	//不能使用encodeURL,必須使用encodeURIComponent,原因是encodeURL不能編碼特殊字符
	str+=`${key}=${encodeURIComponent(obj[key])}&`;
}
console.log(str.replace(/&$/g),'');
//後期獲取URL參數的時候,我們把獲取的值在一次的解碼即可
String.prototype.myQueryUrlParameter=function myQueryUrlParameter(){
	let reg=/[?&]([^?&=]+)(?:=([^?&=]*))?/g,
	obj={};
this.replace(reg,(...arg)=>{
	let [,key,value]=arg;
	obj[key]=decodeURIComponet(value);//此處獲取的時候可以進行解碼
})
    return obj;
}	

也可以通過加密的方法進行編碼解碼
1、可逆轉加密(一般都是自己團隊設置的規則)
2、不可逆轉加密(一般都是基於MD5加密完成的,可能會把MD5加密後的結果二次加密)

AJAX中的同步和異步

ajax這個任務:發送請求接收到響應主體內容(完成一個完整的HTTP事務)
xhr.send():任務開始
xhr.readyState===4:任務結束

let xhr=new XMLHttpRequest();
xhr.open('get','temp.json',false);
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
xhr,send();
//只輸出一次結果,是4

在這裏插入圖片描述

let xhr=new XMLHttpRequest();
xhr.open('get','temp.json',false);
xhr,send();//=>[同步]開始發送AJAX請求,開啓AJAX任務,在任務沒有完成之前,什麼事情都做不了(下面綁定時間也做不了)=>LOADING=>當readyState===4的時候,AJAX任務完成,開始執行下面的操作
//readState===4
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
//綁定方法之前狀態已經爲4了,此時AJAX的狀態不會再改變成其他值,所以事件永遠不會被觸發,一次都妹妹執行方法(使用ajax同步編程,不要把SEND放在事件監聽前,這樣我們無法在綁定的方法中獲取到響應主體的內容)
let xhr=new XMLHttpRequest();
xhr.open('get','temp.json');
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
xhr,send();
//輸出是3次,結果是 2 3 4 

在這裏插入圖片描述

let xhr=new XMLHttpRequest();
xhr.open('get','temp.json');
xhr,send();
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
//輸出是3次,結果是 2 3 4 
let xhr=new XMLHttpRequest();
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
xhr.open('get','temp.json');
xhr,send();
//輸出是4次,1 2 3 4
let xhr=new XMLHttpRequest();
//xhr.readyState===0
xhr,onreadystatechange=()=>{
	console.log(xhr.readystate);
}
xhr.open('get','temp.json',false);
//xhr.readyState===1  同步中AJAX特殊處理的一件事:執行OPEN狀態爲1,會主動把之前監聽的方法執行一次,然後再去執行SEND.
xhr,send();
//xhr.readyState===4 AJAX任務結束,主任務隊列完成
//輸出是2次,1 4
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章