全棧開發工程師學習祕籍 — HTTP和AJAX重點知識

一、成爲全站開發工程師須要掌握的技術棧

全棧(全站)開發工程師(FULL-STACK):先後端本身均可以獨立完成開發javascript

須要使用的技術棧:php

[前端]css

HTML(5) + CSS(3)html

JAVASCRIPT(JQ、VUE、REACT...)前端

[後端]vue

Java (JSP)(最難)html5

Pythonjava

Nodenode

PHP (PHP)mysql

C# (.net ->dot net) (ASP.NET

C

...

[數據庫]

mysql

sql server

oracle(最難數據分析、數據挖掘就是用的這個)

mongodb (和node結合緊密的)

...

[自動化]

git / svn

webpack (基於NODE運行的)

服務器部署工具 iis/apache/nginx...

linux操做系統

insights.stackoverflow.com/survey/2016

二、真實項目的部署流程(以及一點職業發展建議)

前端和後端是如何通訊的?

前端:客戶

後端:服務器端

所謂的全棧,實際上是你能夠實現客戶端和服務器端程序的編寫,並且還能夠實現兩端之間的通訊

客戶端和服務器端是如何通訊的?

職業規劃建議:

培養本身的人脈圈,以及創建本身的影響力

一、壯大本身的綜合能力

二、常常參加一些活動

三、開放分享(作講師分享本身的智慧、寫本身的我的博客作技術分享)

...

本身作一個技術博客

一、本地開發(當前項目能夠在本地預覽)

二、部署到服務器上,讓別人能夠經過域名或者外網訪問

  • 購買域名
  • 把本身作的項目傳到服務器上
  • 讓域名和服務器關聯(DNS解析:域名解析)
  • 在服務器上發佈或者部署咱們的項目(iis、nginx、apache...)

三、作一些推廣(SEO推廣、友情連接交換、技術文章持續更新...)

客戶端和服務器端的交互(通訊)模型:

經過域名找到服務器,經過端口號才能找到服務器裏面具體的對應項目(服務器裏面能夠放多個項目),一臺服務器的端口號是0~65535之間

能夠參考iis部署(比較簡單,可是通常用nginx)

使用FileZilla進行FTP上傳:

經典面試題:當咱們在瀏覽器地址欄中輸入一個URL地址,到最後看到頁面,中間都經歷了哪些事情?

假設咱們訪問的是 https://www.baidu.com/ 這個地址,按下ENTER鍵後,咱們能夠看到百度首頁面:

  1. 百度頁面並無在咱們本身的客戶端本地,咱們是輸入地址後,才請求過來的

  2. 輸入不一樣的域名能夠看到不一樣的頁面

  3. 有的網址是https,有的是http(也有的是ftp)

  4. 須要客戶端聯網才能完成這些事情

  5. ...


都經歷哪些事情?(參考以上:客戶端和服務器端的交互(通訊)模型的圖)

[Request 客戶端的請求階段]

一、首先根據客戶端輸入的域名,到DNS服務器上進行反解析(經過域名找到對應服務器的外網IP)

二、經過找到的外網IP,找到對應的服務器

三、經過在地址欄中輸入的端口號(沒輸入是由於不一樣協議有本身默認端口號)找到服務器上發佈的對應的項目

[Response 服務器端響應階段]

四、服務器獲取到請求資源文件的地址 例如:/stu/index.html,把資源文件中的**原代碼**找到

五、服務器端會把找到的原代碼返回給客戶端(經過HTTP等傳輸協議返回的)

[客戶端瀏覽器自主渲染]

六、客戶端接收到原代碼後,會交給瀏覽器的內核(渲染引擎)進行渲染,最後由瀏覽器繪製出對應的頁面

三、擴展基於iis簡歷本地項目服務完成手機電腦端局域網聯調

cmd 輸入 ipconfig -all 查看電腦ip地址

iis部署操做如圖

手機也能夠經過這個地址(ip+端口)進行訪問

四、客戶端和服務器交互模型詳解(解讀面試題)

客戶端和服務器端的交互(通訊)模型:

見=>經典面試題:當咱們在瀏覽器地址欄中輸入一個URL地址,到最後看到頁面,中間都經歷了哪些事情?

五、HTTP等傳輸協議講解 ~ 六、HTTP報文的一些核心知識 ~ 八、一個完整URL各部份內容及其做用

URL、URI、URN

URI:統一資源標識符

URL:統一資源路徑地址

URN:統一資源名稱

URI = URL + URN

一個完整的URL包含不少部分:

www.html5train.com/stu/index.h…

問號後面的值都是傳給服務器的,服務器也能夠把這些值拿到而且返回內容

第一部分:傳輸協議

傳輸協議是用來完成客戶端和服務器端的數據(內容)傳輸的,相似於快遞小哥,負責把客戶和商家的物品來回傳送

一、客戶端不只能夠向服務器發送請求,並且還能夠把一些內容傳遞給服務器 (好比問號後面的值都是傳給服務器的)

二、服務器端也能夠把內容返回給客戶端

客戶端和服務器端傳輸的內容總稱HTTP報文,這些報文信息都是基於傳輸協議完成傳輸的,客戶端傳遞給服務器叫作請求(request),服務器返回給客戶端叫作響應(response),request+response兩個階段統稱爲一個HTTP事務(事務:一件完整的事情)

HTTP事務:

一、當客戶端向服務器端發送請求,此時客戶端和服務器端會創建一個傳輸通道(連接通道),傳輸協議就是基於這個通道把信息進行傳輸的

二、當服務器端接受到請求信息,把內容返回給客戶端後,傳輸通道會自動銷燬關閉

傳輸協議分類:

http:超文本傳輸協議(客戶端和服務器端傳輸的內容除了文本之外,還能夠傳輸圖片、音視頻等文件流[二進制編碼/BASE64碼],以及傳輸xml格式的數據等),是目前市場上應用最廣範的傳輸協議

https:http ssl,它比http更加安全,由於數據內容的傳輸通道是通過ssl加密的(它須要在服務器端進行特殊的處理),因此涉及資金類的網站通常都是https協議的

ftp:資源文件傳輸協議,通常用於客戶端把資源文件(不是代碼)上傳到服務器端,或者從服務器端下載一些資源文件(通常ftp傳輸的內容會比http這類協議傳輸的內容多)

...

HTTP報文:

一、起始行

請求起始行

響應起始行

二、首部(頭)

請求頭:內置請求頭、自定義請求頭

響應頭:內置響應頭、自定義響應頭

通用頭:請求和響應都有的

三、主體

請求主體

響應主體

請求XXX都是客戶端設置的信息,服務器端獲取這些信息

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

在谷歌瀏覽器控制檯Network選項中,咱們能夠看見當前客戶端和服務器端交互的所有信息

總結:

客戶端傳遞給服務器端數據

一、URL問號傳遞參數

二、設置請求頭(內置請求頭、自定義請求頭)

三、設置請求主體

...

服務器端返回給客戶端內容

一、設置響應頭(例如服務器時間)

二、設置響應主體

...

第二部分:域名

設置域名其實就給很差記憶的服務器外網IP設置了一個好記憶的名字

頂級域名(一級域名):qq.com

二級域名:www.qq.comv.qq.comsports.qq.com ...

三級域名:kbs.sports.qq.com

...

第三部分:端口號

在服務器發佈項目的時候,咱們能夠經過端口號區分當前服務器上不一樣的項目

一臺服務器的端口號取值範圍:0~65535之間,若是電腦上安裝了不少程序,有一些端口號是被佔用了

HTTP:默認端口號80

HTTPS:默認端口號443

FTP:默認端口號21

對於上述三個端口號實際上是很重要的,若是被其它程序佔用,咱們則不能使用了;因此服務器上通常是禁止安裝其它程序的;

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

/stu/index.html

在服務器中發佈項目的時候,咱們通常都會配置一些默認文檔:用戶即便不輸入請求文件的名稱,服務器也會找到默認文檔(通常默認文檔都是index/default...)

咱們一般爲了作SEO優化,會把一些動態頁面的地址(xxx.php、xxx.aspx、xxx.asp、xxx.jsp...)進行僞URL重寫(須要服務器處理的)

item.jd.com/4325427.htm… 不多是有一個商品,本身就單獨寫一個詳情頁面,確定是同一個詳情頁作的不一樣處理

1)第一種方案:

由後臺語言根據詳情頁模板動態生成具體的詳情頁面

2)第二種方案:

當前頁面就是一個頁面,例如:detail.html(先後端徹底分離) / detail.php(不是先後端徹底分離)...,咱們作詳情頁面的時候,開發是按照 detail.html?id=4325427 來開發的;可是這種頁面不方便作SEO優化,此時咱們把真實的地址進行重寫,重寫爲咱們看到的 4325427.html

第五部分:問號傳參

?name=zf&age=9....

把一些值經過xxx=xxx的方式,放在一個URL的末尾,經過問號傳遞

[做用]

一、在AJAX請求中,咱們能夠經過問號傳遞參數的方式,客戶端把一些信息傳遞給服務器,服務器根據傳遞信息的不同,返回不一樣的數據

//=>$.ajax(url,{});
//=>$.get(url,function(){}); 對於AJAX請求的特殊寫法,原理仍是基於AJAX方法實現的  $.post / $.script ...

$.ajax({
	url:'getPersonInfo?id=12'
	...
});
//=>當前案例,咱們傳遞給服務器的編號是多少,服務器端就會把對應編號人員信息給返回
複製代碼

二、消除AJAX請求中GET方式緩存

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

三、經過URL傳遞參數的方式,能夠實現頁面之間信息的通訊,例如:咱們有兩個頁面A/B,A是列表頁面,B是詳情頁,點擊A中的某一條信息,進入到惟一的詳情頁B,如何展現不一樣的信息,這種操做就能夠基於URL問號傳遞參數來實現了

例如:

sports.qq.com/kbsweb/game…

sports.qq.com/kbsweb/game…

在進入到game.htm頁面的時候,咱們能夠獲取URL傳遞的參數值,根據傳遞參數值的不同,從服務器端獲取不一樣的數據展現

在列表頁面進行頁面跳轉的時候,咱們須要記住的是跳轉的同時傳遞不一樣的參數值

<a href='game.html?mid=xxxx'>
複製代碼

除了問號傳參能夠實現頁面之間信息的通訊之外,還有什麼方式能夠實現頁面之間的通訊

問號傳參:(經常使用)

本地存儲:A頁面裏面把一些信息存到本地,B頁面當中能夠從本地把這些信息拿到(好比登陸、註冊成功以後其餘頁面要獲取到用戶的信息)

iframe:把一個頁面看成當前頁面的子頁面嵌套到當前頁面中,這個頁面就能夠獲取到這個嵌套頁面中的信息了

第六部分:HASH值

#xxx

URL末尾傳遞的井號什麼,就是HASH值(哈希值)

[做用]

一、頁面中錨點定位

二、前端路由(SPA單頁面開發)

七、WEB前端開發經常使用的優化技巧彙總

減小HTTP請求次數或者減小請求數據的大小

頁面中每發送一次HTTP請求,都須要完成請求+響應這個完整的HTTP事務,會消耗一些時間,也可能會致使HTTP連接通道的堵塞,爲了提升頁面加載速度和運行的性能,咱們應該減小HTTP的請求次數和減小請求內容的大小(請求的內容越大,消耗的時間越長)

瀏覽器在一行行解析服務器返回的內容時,解析html須要發送一次http請求,每解析html中的link,script,img標籤時須要發送http請求(從這些方面去考慮)

一、採用CSS雪碧圖(CSS Sprit / CSS 圖片精靈)技術,把一些小圖合併在一張大圖上,使用的時候經過背景圖片定位,定位到具體的某一張小圖上

//css
.pubBg{
	background:url('../img/sprit.png') no-repeat;//只須要發送一次http請求
	background-size:x y; /*和原圖的大小保持一致*/
}
.box{
	background-position:x y; /*經過背景定位,定位到具體的位置,展現不一樣的圖片便可*/
}
//html
<div class='pubBg box'></div>
複製代碼

二、真實項目中,咱們最好把CSS或者JS文件進行合併壓縮;尤爲是在移動端開發的時候,若是CSS或者JS內容不是不少,咱們能夠採起內嵌式,以此減小HTTP請求的次數,加快頁面加載速度;

1)CSS合併成一個,JS也最好合併成一個

2)首先同過一些工具(例如:webpack)把合併後的CSS或者JS壓縮成 xxx.min.js,減小文件大小

3)服務器端開啓資源文件的GZIP壓縮

...

經過一些自動化工具完成CSS以及JS的合併壓縮,或者再完成LESS轉CSS,ES6轉ES5等操做,咱們把這種自動化構建模式,稱之爲前端「工程化」開發

三、採用圖片懶加載技術,在頁面開始加載的時候,不請求真實的圖片地址,而是用默認圖佔位,當頁面加載完成後,在根據相關的條件依次加載真實圖片(減小頁面首次加載HTTP請求的次數)

真實項目中,咱們開始圖片都不加載,頁面首次加載完成,先把第一屏幕中能夠看見的圖片進行加載,隨着頁面滾動,在把下面區域中可以呈現出來的圖片進行加載

根據圖片懶加載技術,咱們還能夠擴充出,數據的懶加載

1)開始加載頁面的時候,咱們只把首屏或者前兩屏的數據從服務器端進行請求(有些網站首屏數據是後臺渲染好,總體返回給客戶端呈現的)

有些網站的首屏數據多是服務器給你渲染好返回過來的,也有多是服務器返回的就是一個完整的html、css(服務器給你返回的不是json格式數據了,而是一個完整html文檔,客戶端只須要展現就好了)可是服務器渲染有個弊端就是壓力大,可是比客戶端渲染快(客戶端向服務器端發送請求,服務器端把全部數據拿到,把這些數據經過html、css拼接成字符串,能夠直接渲染到頁面中,也能夠經過ajax的方式以文檔的形式返回,而後客戶端在頁面中呈現,減小了客戶端本身綁定數據的過程)

像京東、淘寶首屏通常就是服務器端渲染加載的,第二屏多是客戶端進行渲染,無論是客戶端渲染仍是服務器端渲染,剛開始只是把首屏或者前兩屏的數據從服務器端進行請求渲染出來。接下來第 2)當頁面下拉

2)當頁面下拉,滾動到哪一個區域,在把這個區域須要的數據進行請求(請求回來作數據綁定以及圖片延遲加載等)

3)分頁展現技術採用的也是數據的懶加載思想實現的:若是咱們請求獲取的數據是不少的數據,咱們最好分批請求,開始只請求第一頁的數據,當用戶點擊第二頁(微博是下拉到必定距離後,再請求第二頁數據...)的時候在請求第二頁數據...

四、對於不常常更新的數據,最好採用瀏覽器的304緩存作處理(主要由服務器端處理)

例如:

第一次請求css和js下來,瀏覽器會把請求的內容緩存起來,若是作了304處理,用戶再次請求css和js,直接從緩存中讀取,不須要再去服務器獲取了(減小了HTTP請求次數)

當用戶強制刷新頁面(CTRL+F5)或者當前緩存的CSS或者JS發生了變更,都會重新從服務器端拉取

...

對於客戶端來說,咱們還能夠基於localStorage來作一些本地存儲,例如:第一次請求的數據或者不常常更新的CSS和JS,咱們均可以把內容存儲在本地,下一次頁面加載,咱們從本地中獲取便可,咱們設定必定的期限或者一些標識,能夠控制在某個階段從新從服務器獲取

五、使用字體圖標代替一些頁面中的位圖(圖片),這樣不只作適配的時候方便,並且更加輕量級,並且減小了HTTP請求次數(相似於雪碧圖)

六、若是當前頁面中出現了AUDIO或者VIDEO標籤,咱們最好設置它們的preload=none:頁面加載的時候,音視頻資源不進行加載,播放的時候再開始加載(減小頁面首次加載HTTP請求的次數)

preload=auto:頁面首次加載的時候就把音視頻資源進行加載了

preload=metadata:頁面首次加載的時候只把音視頻資源的頭部信息進行加載

...

七、在客戶端和服務器端進行數據通訊的時候,咱們儘可能採用JSON格式進行數據傳輸

[優點]

1)JSON格式的數據,可以清晰明瞭的展現出數據結構,並且也方便咱們獲取和操做

2)相對於很早之前的XML格式傳輸,JSON格式的數據更加輕量級

3)客戶端和服務器端都支持JSON格式數據的處理,處理起來很是的方便

真實項目中,並非全部的數據都要基於JSON,咱們儘量這樣作,可是對於某些特殊需求(例如:文件流的傳輸或者文檔傳輸),使用JSON就不合適了

八、採用CDN加速

CDN:分佈式(地域分佈式)

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

除了減小HTTP請求次數和大小能夠優化性能,咱們在編寫代碼的時候,也能夠進行一些優化,讓頁面的性能有所提高(有些很差的代碼編寫習慣,會致使頁面性能消耗太大,例如:內存泄漏)

一、在編寫JS代碼的時候,儘可能減小對DOM的操做(VUE和REACT框架在這方面處理的很是不錯)

在JS中操做DOM是一個很是消耗性能的事情,可是咱們又不可避免的操做DOM,咱們只能儘可能減小對於它的操做

[操做DOM弊端]

1)DOM存在映射機制(JS中的DOM元素對象和頁面中的DOM結構是存在映射機制的,一改則都改),這種映射機制,是瀏覽器按照W3C標準完成對JS語言的構建和DOM的構建(其實就是構建了一個監聽機制),操做DOM是同時要修改兩個地方,相對於一些其它的JS編程來講是消耗性能的

2)頁面中的DOM結構改變或者樣式改變,會觸發瀏覽器的迴流(瀏覽器會把DOM結構從新進行計算,這個操做很耗性能)和重繪(把一個元素的樣式從新渲染)

...

二、編寫代碼的時候,更多的使用異步編程

同步編程會致使:上面東西完不成,下面任務也作不了,咱們開發的時候,能夠把某一個區域模塊都設置爲異步編程,這樣只要模塊之間沒有必然的前後順序,均可以獨立進行加載,不會受到上面模塊的堵塞影響(用的很少)

尤爲是AJAX數據請求,咱們通常都要使用異步編程,最好是基於promise設計模式進行管理(項目中常用 fetch、vue axios 等插件來進行AJAX請求處理,由於這些插件中就是基於promise設計模式對ajax進行的封裝處理)

三、在真實項目中,咱們儘量避免一次性循環過多數據(由於循環操做是同步編程),尤爲是要避免while致使的死循環操做

四、CSS選擇器優化

1)儘可能減小標籤選擇器的使用

2)儘量少使用ID選擇器,多使用樣式類選擇器(通用性強)

3)減小選擇器前面的前綴,例如:.headerBox .nav .left a{ } (選擇器是從右向左查找的)=> 起名字的時候作優化.header-nav-left a{}

...

五、避免使用CSS表達式

/*CSS表達式*/
.box{
	background-color:expression((new Date()).getHours()%2?'red':'blue')
}
複製代碼

六、減小頁面中的冗餘代碼,儘量提升方法的重複使用率:「低耦合高內聚」 => 也是類封裝的目的

七、最好CSS放在HEAD中,JS放在BODY尾部,讓頁面加載的時候,先加載CSS,在加載JS(先呈現頁面,在給用戶提供操做)

八、JS中避免使用eval

1)性能消耗大

2)代碼壓縮後,容易出現代碼執行錯亂問題

九、JS中儘可能減小閉包的使用

1)閉包會造成一個不銷燬的棧內存,過多的棧內存累積會影響頁面的性能

2)還會容易致使內存的泄漏

閉包也有本身的優點:保存和保護,咱們只能儘可能減小,可是無可避免

十、在作DOM事件綁定的時候,儘可能避免一個個的事件綁定,而是採用性能更高的事件委託來實現

事件委託(事件代理)

把事件綁定給外層容器,當裏面的後代元素相關行爲被觸發,外層容器綁定的方法也會被觸發執行(冒泡傳播機制致使),經過事件源是誰,咱們作不一樣的操做便可

十一、儘可能使用CSS3動畫代替JS動畫,由於CSS3的動畫或者變形都開啓了硬件加速,性能比JS動畫好

十二、編寫JS代碼的時候儘量使用設計模式來構建體系,方便後期的維護,也提升了擴充性等

1三、CSS中減小對濾鏡的使用,頁面中也減小對於FLASH的使用

關於頁面的SEO優化技巧

一、頁面中杜絕出現死連接(404頁面),並且對於用戶輸入一個錯誤頁面,咱們要引導到404提示頁面中(服務器處理的)

二、避免瀏覽器中異常錯誤的拋出

儘量避免代碼出錯

使用TRY CATCH作異常信息捕獲

...

三、增長頁面關鍵詞優化

見WEEK8-1-BASE面試題彙總

九、什麼是AJAX(先後端分離和不分離的優點弊端)

AJAX基礎知識

什麼是AJAX?

async javascript and xml,異步的JS和XML

xml:可擴展的標記語言

做用是用來存儲數據的(經過本身擴展的標記名稱清晰的展現出數據結構)以下:

WEEK8-temp.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <student>
        <name>張三</name>
        <age>25</age>
        <score>
            <english>90</english>
            <math>100</math>
            <chinese>98</chinese>
        </score>
    </student>
    <student>
        <name>李四</name>
        <age>24</age>
        <score>
            <english>80</english>
            <math>90</math>
            <chinese>100</chinese>
        </score>
    </student>
</root>
複製代碼

ajax之因此稱爲異步的js和xml,主要緣由是:當初最開始用ajax實現客戶端和服務器端數據通訊的時候,傳輸的數據格式通常都是xml格式的數據,咱們咱們把它稱之爲異步js和xml(如今通常都是基於JSON格式來進行數據傳輸的)

異步的JS

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

局部刷新 VS 全局刷新

在非徹底先後端分離項目中,前端開發只須要完成頁面的製做,而且把一些基礎的人機交互效果使用js完成便可,頁面中須要動態呈現內容的部分,都是交給後臺開發工程師作數據綁定和基於服務器進行渲染的(服務器端渲染)

[優點]

一、動態展現的數據在頁面的原代碼中能夠看見,有利於SEO優化推廣(有利於搜索引擎的收錄和抓取)

二、從服務器端獲取的結果就已是最後要呈現的結果了,不須要客戶端作額外的事情,因此頁面加載速度快(前提是服務器端處理的速度夠快,可以處理過來),因此相似於京東、淘寶這些網站,首屏數據通常都是經由服務器端渲染的

[弊端]

一、若是頁面中存在須要實時更新的數據,每一次想要展現最新的數據,頁面都要從新的刷新一次,這樣確定不行

二、都交給服務器端作數據渲染,服務器端的壓力太大,若是服務器處理不過來,頁面呈現的速度更慢(因此京東淘寶這類網站,除了首屏是服務器端渲染的,其它屏通常都是客戶端作數據渲染綁定)

三、這種模式不利於開發(開發效率低)

非徹底先後端分離如圖:

目前市場上大部分項目都是先後端徹底分離的項目(也有非徹底先後端分離的)

先後端徹底分離的項目,頁面中須要動態綁定的數據是交給客戶端完成渲染的

一、向服務器端發送AJAX請求

二、把從服務器端獲取的數據解析處理,拼接成爲咱們須要展現的HTML字符串

三、把拼接好的字符串替換頁面中某一部分的內容(局部刷新),頁面總體不須要從新加載,局部渲染便可

[優點]

一、咱們能夠根據需求,任意修改頁面中某一部分的內容(例如實時刷新),總體頁面不刷新,性能好,體驗好(全部表單驗證、須要實時刷新的等需求都要基於AJAX實現)

二、有利於開發,提升開發的效率

1)先後端的徹底分離,後臺不須要考慮前端如何實現,前端也不須要考慮後臺用什麼技術,真正意義上實現了技術的劃分

2)能夠同時進行開發:項目開發開始,首先制定先後端數據交互的接口文檔(文檔中包含了,調取哪一個接口或者哪些數據等協議規範),後臺把接口先寫好(目前不少公司也須要前端本身拿NODE來模擬這些接口),客戶端按照接口調取便可,後臺再次去實現接口功能便可

[弊端]

一、不利於SEO優化:第一次從服務器端獲取的內容不包含須要動態綁定的數據,因此頁面的源代碼中沒有這些內容,不利於SEO收錄,後期經過JS添加到頁面中的內容,並不會寫在頁面的源代碼中(是源代碼不是頁面結構)

二、交由客戶端渲染,首先須要把頁面呈現,而後再經過JS的異步AJAX請求獲取數據,而後數據綁定,瀏覽器在把動態增長的部分從新渲染,無形中浪費了一些時間,沒有服務器端渲染頁面呈現速度快

先後端徹底分離:

十、GET請求和POST請求的區別

基於原生JS實現AJAX

//=>建立一個AJAX對象
let xhr=new XMLHttpRequest();//=>不兼容IE6及更低版本瀏覽器(IE6:ActiveXObject)

//=>打開請求地址(能夠理解爲一些基礎配置,可是並無發送請求呢)
xhr.open([method],[url],[async],[user name],[user 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],[user password])

[AJAX請求方式]

一、GET系列的請求(獲取)

get

delete:從服務器上刪除某些資源文件

head:只想獲取服務器返回的響應頭信息(響應主體內容不須要獲取)

...

二、POST系列請求(推送)

post

put:向服務器中增長指定的資源文件

...

無論哪種請求方式,客戶端均可以把信息傳遞給服務器,服務器也能夠把信息返回給客戶端,只是GET系列通常以獲取爲主(給的少,拿回來的多),而POST系列通常以推送爲主(給的多,拿回來的少)

1)咱們想獲取一些動態展現的信息,通常使用GET請求,由於只須要向服務器端發送請求,告訴服務器端咱們想要什麼,服務器端就會把須要的數據返回

2)在實現註冊功能的時候,咱們須要把客戶輸入的信息發送給服務器進行存儲,服務器通常返回成功仍是失敗等狀態,此時咱們通常都是基於POST請求完成

...

GET系列請求和POST系列請求,在項目實戰中存在不少的區別

一、GET請求傳遞給服務器的內容通常沒有POST請求傳遞給服務器的內容多

緣由:GET請求傳遞給服務器內容通常都是基於url地址問號傳遞參數來實現的,而POST請求通常都是基於設置請求主體來實現的。

各瀏覽器都有本身的關於URL最大長度的限制(谷歌:8KB、火狐:7KB、IE:2KB...)超過限制長度的部分,瀏覽器會自動截取掉,致使傳遞給服務器的數據缺失。

理論上POST請求經過請求主體傳遞是沒有大小限制的,真實項目中爲了保證傳輸的速率,咱們也會限制大小(例如:上傳的資料或者圖片咱們會作大小的限制)

二、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);
複製代碼

三、GET請求沒有POST請求安全(POST也並非十分安全,只是相對安全)

緣由:仍是由於GET是URL傳參給服務器

有一種比較簡單的黑客技術:URL劫持,也就是能夠把客戶端傳遞給服務器的數據劫持掉,致使信息泄露

十一、關於OPEN中剩下的幾個參數意思

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

ASYNC:異步(SYNC同步),設置當前AJAX請求是異步的仍是同步的,不寫默認是異步(TRUE),若是設置爲FALSE,則表明當前請求是同步的

用戶名和密碼:這兩個參數通常不用,若是你請求的URL地址所在的服務器設定了訪問權限,則須要咱們提供可通行的用戶名和密碼才能夠(通常服務器都是能夠容許匿名訪問的)

十二、AJAX狀態碼和網絡狀態碼講解

第三部分細節研究

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

AJAX狀態碼:描述當前AJAX操做的狀態的

xhr.readyState

0:UNSENT 未發送,只要建立一個AJAX對象,默認值就是零

1:OPENED 咱們已經執行了xhr.open這個操做

2:HEADERS_RECEIVED 當前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 服務器超負載(作不了負載均衡) ...

1三、AJAX中的其餘經常使用屬性和方法詳解

AJAX中其餘經常使用的屬性和方法

面試題:AJAX中總共支持幾個方法?

let xhr = new XMLHttpRequest();
console.dir(xhr);
複製代碼

[屬性]

readyState:存儲的是的當前ajax的狀態碼

response/responseText/responseXML:都是用來接收服務器返回的相應主體中的內容,只是根據服務器返回的內容的格式不同,咱們使用不一樣的屬性接收便可

  • responseText是最經常使用的,接收的結果是字符串格式的(通常服務器返回的數據都是json格式字符串)

  • responseXML偶爾會用到,若是服務器端返回的是xml文檔數據,咱們須要使用這個屬性接收

status:記錄了服務器端返回的http狀態碼

statusText:對返回狀態碼的描述

timeout:設置當前ajax請求的超時時間,假設咱們設置時間爲3000ms,從ajax請求發送開始,3秒後響應主體內容尚未返回,瀏覽器會把當前ajax請求任務強制斷開

[方法]

about():強制中斷ajax請求

getAllResponseHeaders():獲取所有的響應頭信息(獲取的結果是一堆字符串文本)

getResponseHeader():獲取指定屬性名的響應頭信息,例如:xhr.getResponseHeader('date')獲取響應頭中存儲的服務器的時間

open():打開一個url地址

overrideMimeType():重寫數據的MIME類型

send():發送ajax請求(括號中書寫的內容時客戶端基於請求主體把信息傳遞給服務器)

setRequestHeader(key,value):設置請求頭信息(能夠是設置的自定義請求頭信息)

[事件]

onabort:當ajax被中斷請求觸發這個事件

onreadystatechange:ajax狀態發生改變,會觸發這個事件

ontimeout:當ajax請求超時,會觸發這個事件

...

WEEK8-2-AJAX-1-ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script src="1.js"></script>
</body>
</html>
複製代碼

WEEK8-2-AJAX-1.js

let xhr = new XMLHttpRequest();
// xhr.setRequestHeader('aaa','xxx');//設置請求頭必須在open以後和send以前
xhr.open('get','temp.json?='+Math.random().true);
xhr.open('get','temp.xml?='+Math.random().true);
// xhr.setRequestHeader('cookie','嗨');//設置的請求頭內容不是一個有效的值(請求頭部的內容中不得出現中文漢字)
xhr.setRequestHeader('aaa','xxx');
// 設置超時
xhr.timeout = 10;
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');//獲取的服務器時間是格林尼治時間(相比於北京時間差了8小時)
            console.log(headerAll,new Date(serverDate));//經過new Date()能夠把這個時間轉換爲北京時間
            return;
    }

    // 在狀態爲4的時候響應主體內容就已經回來了
    if(state === 4){
        let valueText = xhr.responseText,//獲取到的結果通常的都是json字符串(可使用JSON.PARSE轉換爲json對象)
            valueXML = xhr.responseXML;//獲取到的結果是xml格式的數據(能夠經過xml的一些常規操做獲取存儲的指定信息)若是服務器返回的是xml文檔,
            // responseText獲取的結果是字符串而responseXML獲取的是標準xml文檔
            console.log(valueText,valueXML);
    }



}
xhr.send('name=sjb&age=24&sex=man');
複製代碼

WEEK8-2-AJAX-temp.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <student>
        <name>張三</name>
        <age>25</age>
        <score>
            <english>90</english>
            <math>100</math>
            <chinese>98</chinese>
        </score>
    </student>
    <student>
        <name>李四</name>
        <age>24</age>
        <score>
            <english>80</english>
            <math>90</math>
            <chinese>100</chinese>
        </score>
    </student>
</root>
複製代碼

WEEK8-2-AJAX-temp.json

[
    {
        "name":"張三",
        "age":25,
        "score":{
            "english":95,
            "math":100,
            "chinese":98
        }
    },
    {
        "name":"李四",
        "age":25,
        "score":{
            "english":95,
            "math":100,
            "chinese":98
        }
    }
]
複製代碼

1四、js中經常使用的內容編碼和加密解密方法

正常的編碼解碼(非加密)

一、escape/unescape:主要就是把中文文字進行編碼和解碼的(通常只有js語言支持;也常常應用於前端頁面通訊時候的中文漢字編碼,好比須要把a頁面的中文數據傳遞給b頁面,b頁面拿到亂碼了,就須要在a頁面把這些中文數據信息經過escape進行編碼,b頁面中經過unescape解碼)

二、encodeURI/decodeURI:基本上全部的編程語言都支持

三、encodeURIComponent/decodeURIComponent:和第二種方式很是相似,區別在於

需求:咱們URL問號傳遞參數的時候,咱們傳遞的參數值仍是一個url或者包含不少特殊的字符,此時爲了避免影響主要的url,咱們須要把傳遞的參數值進行編碼。使用encodeURI不能編碼一些特殊字符,因此只能使用encodeURIComponent處理

let str = 'http://www.baidu.com/?',
obj = {
    name:'嗨嗨嗨',
    age:9,
    url:'http://www.1626.com/?lx=1'
};
// 把obj中的每一項屬性名和屬性值拼接到url的末尾(問號傳參方式)
for(let key in obj){
    str+=`${key}=${encodeURIComponent(obj[key])}&`;
    // 不能使用encodeURI,必須使用encodeURIComponent,緣由是encodeURI不能編碼特殊的字符
}
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]=decodeURIComponent(value);//此處獲取的時候能夠進行解碼 
    });
    return obj;
}
複製代碼

也能夠經過加密的方法進行編碼解碼

一、可逆轉加密(通常都是團隊本身玩的規則)

二、不可逆轉加密(通常都是基於MD5加密完成的,md5加密後的結果沒有什麼規則能夠把它解密,可能會把MD5加密後的結果二次加密)密碼就是隻能加密不能解密的,就會用md5來加密密碼的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script src="md5.min.js"></script>
</body>
</html>
複製代碼

1五、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的時候ajaxj任務完成,開始執行下面的操做
// readyState===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.readyState===1
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();
// 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任務結束,主任務隊列完成
// 1 4
複製代碼

1六、綜合實戰案列之倒計時搶購

ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id='box'></div>
    <script src="3.js"></script>
</body>
</html>
複製代碼

3.js

~function(){
    let box = document.getElementById('box'),
        serverTime = null;
    let fn = () => {
        //一、 計算當前時間和目標時間的差值

        // let nowTime = new Date(),//獲取的是客戶端本機時間(會受到客戶端本身調整時間的影響),重要的事件參考不能基於這個完成,無論是哪個
        // // 客戶端都須要基於相同的服務器時間計算

        // let nowTime = serverTime,

        //每間隔1s中,咱們須要把第一次獲取的服務器時間進行累加
        serverTime = serverTime +1000;

        let tarTime = new Date('2018/12/1 9:29:00').getTime(),//2017/12/14  斜槓在ie下才能轉換  中槓在ie下不能轉換  這裏用斜槓
            // spanTime = tarTime - nowTime;
            spanTime = tarTime - serverTime;

        //二、 計算差值中包含多少時分秒
        if(spanTime<0){
            // 已經錯過了搶購的事件(已經開槍了)
            box.innerHTML = '開槍';
            clearInterval(autoTimer);
            return;
        }

        let hours = Math.floor(spanTime/(1000*60*60));
        spanTime -= hours * 3600000;
        let minus = Math.floor(spanTime/(1000*60));
        spanTime -= minus * 60000;
        let seconds = Math.floor(spanTime/1000);
        hours<10?hours='0'+hours:null;
        minus<10?minus='0'+minus:null;
        seconds<10?seconds='0'+seconds:null;
        box.innerHTML=`距離開槍還剩下${hours}:${minus}:${seconds}`;
    };

    let autoTimer = setInterval(fn,1000);

    // 從服務器端獲取服務器時間
    let getServerTime = () => {
        let xhr = new XMLHttpRequest();
       
         xhr.onreadystatechange = ()=>{
                console.log(xhr.readyState);//head請求方式,狀態碼中沒有3(由於不須要等待響應主體內容)

                if(!/^(2|3)\d{2}$/.test(xhr.status)) return;
                if(xhr.readyState===2){
                    serverTime = new Date(xhr.getResponseHeader('date')).getTime();
                   
                    fn();
                }


        }
      
        xhr.open('head','temp.xml',true);//head請求比get請求快,get請求包含主題內容,head不用獲取主題內容
        xhr.send(null);


        // 獲取服務器時間總會出現時間差的問題:服務器端把時間記錄好,到客戶端獲取到時間有延遲差(服務器返回的時候記錄的是10:00,
        // 咱們客戶端獲取的時候已是10:01,可是咱們獲取的結果依然是10:00,這樣就有1分鐘時間差)

        // [儘量的減小時間差,是咱們優化的所有目的]

        // 一、服務器返回的時間在響應頭信息中就有,咱們只須要獲取響應頭信息便可,不必獲取響應主體內容,
        // 因此請求方式使用 head 便可
        // 二、必須使用異步編程:同步編程咱們沒法再狀態爲2或者3的時候作一些處理,而咱們獲取響應頭信息,在狀態爲2
        // 的時候就能夠獲取了,因此須要使用異步
        // 三、在狀態爲2的時候就把服務器時間獲取到
        // ...




    };

    getServerTime();

}();
複製代碼

面試官可能會問,項目中有沒有作倒計時功能?怎麼作的和處理的?

(其實想問ajax的優化技巧,就是以上代碼)

1七、jq中ajax操做詳解

jq中的ajax使用及每個配置的做用(包含裏面的一些細節知識)

$.ajax({
    url:'xxx.txt',//請求api地址
    method:'get',//請求方式get/post...在老版本jq中使用的是type,使用type和method實現的是相同的效果
    dataType:'json',//dataType只是咱們預設獲取結果的類型,不會影響服務器的返回(服務器端通常給咱們返回的都是json
    // 格式字符串),若是咱們預設的是json,那麼類庫中將把服務器返回的字符串轉換爲json對象,若是咱們預設的是text(默認值),
    // 咱們把服務器獲取的結果直接拿過來操做便可,咱們預設的值還能夠是xml等
    cache:false,//設置是否清除緩存,支隊get系列請求有做用,默認是ture不清緩存,手動設置爲false,jq類庫會在請求url的末尾追加一個隨機數來清除緩存
    data:null,//咱們經過data能夠把一些信息傳遞給服務器;get系列請求會把data中的內容拼接在url的末尾經過問號傳參的方式傳遞給服務器,post系列請求會把內容
    // 放在請求主題中傳遞給服務器;data的值能夠設置爲兩種格式:字符串、對象,若是是字符串,設置的值是什麼傳遞給服務器的就是什麼,若是設置的是對象,jq會把對象變爲
    // xxx = xxx&xxx = xxx 這樣的字符串傳遞給服務器
    async:true,//設置同步或者異步,默認是true表明異步,false是同步
    success:function(result){
        // 當ajax請求成功(readyState===4&status是以2或者3開頭的)
        // 請求成功後jq會把傳遞的回調函數執行,而且把獲取的結果當作實參傳遞給回調函數(result就是咱們從服務器端獲取的結果)
    },
    error:function(msg){
        // 請求錯誤觸發回調函數
    },
    complate:function(){
        // 無論請求是錯誤的仍是正確的都會觸發回調函數(它是完成的意思)
    },
    // ...
});
複製代碼

1八、封裝本身的ajax庫

支持的參數

url

method/type

data

dataType

async

cache

success

...

基於構造函數的結構

~function(){
    class ajaxClass {

    }
    window.ajax = function({
        url = null,
        method = 'GET',
        type = 'GET',
        data = null,
        dataType = 'JSON',
        cache = true,
        async = true,
        success = null
    }={}){

    };
}();
ajax({});
複製代碼

基於構造函數封裝ajax類庫

ajax.js

~function(){
    class ajaxClass {
        // 執行ajax
        init(){
            // this:examplenpm
            let xhr = new XMLHttpRequest();
            xhr.onreadystatechange = () => {
                if(!/^[23]\d{2}$/.test(xhr.status)) return;
                if (xhr.readyState === 4) {
                    let result = xhr.responseText;
                    // data-type處理  從服務器獲得的結果result,而dataType是把從服務器獲得的result結果進行二次處理
                    try {
                        switch (this.dataType.toUpperCase()){
                            case 'TEXT':
                            case 'HTML':
                                result = result;
                                break;
                            case 'JSON':
                                result = JSON.parse(result);
                                break;
                            case 'XML':
                                result = xhr.responseXML;
                        }
                    } catch (e) {
                        
                    }
                 

                    this.success(result);
                }

            };

            // Data處理 若是data是對象須要轉換成字符串 若是是get請求 把data放在url末尾  
            if (this.data !== null) {
                this.formatData();

                if (this.isGET) {
                    this.url += this.querySymbol() + this.data;
                    this.data = null;
                }
            }

            // cache緩存處理 若是當前請求是get請求(this.isGET爲true時是get請求)而且cache傳遞的是flase,須要緩存處理
            // (在當前url末尾增長隨機數),因此在open發送以前 處理url
            this.isGET ? this.cacheFn() : null;
            xhr.open(this.method, this.url, this.async);
            xhr.send(this.data);

        }

        // 把傳遞的對象格式data轉換爲字符串格式data
        formatData() {
            // this:examplenpm
            // if(typeof this.data === 'object') { //這樣判斷不許確  null也是對象格式
            // if(({}).toString.call(this.data) === '[object Object]') { //準確判斷  等價於
            if(Object.prototype.toString.call(this.data) === '[object Object]') {
                let obj = this.data,
                    str = ``;
                for (let key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        str += `${key}=${obj[key]}&`;
                    }
                }
                // 去掉轉換成字符串拼接後的最後一個&
                str = str.replace(/&$/g, '');
                this.data = str;
            }

        }

        cacheFn() {
            // this:examplenpm
            // if (this.cache === false) { //cache傳遞的是flase,須要緩存處理

            // if (!this.cache) {//cache傳遞的是flase,須要清除緩存
            //     // 'xxx.html?_='+隨機數 可是問號後面可能還有參數  以下:
            //     // 'xxx.html?name=xxx&_='+隨機數
            //     // 因此須要驗證當前url裏面是否存在問號,存在問號須要加&,不存在問號就用問號

            // }

            !this.cache ? this.url += `${this.querySymbol()}_=${Math.random()}` : null;

        }

        // 驗證當前url裏面是否存在問號,存在問號須要加&,不存在問號就用問號
        querySymbol() {
            // this:examplenpm
            return this.url.indexOf('?') > -1 ? '&' : '?';
        }



    }

    //參數初始化  如下代碼也能夠在constructor中完成
    window.ajax = function({
        url = null,
        method = 'GET',
        type = 'GET',
        data = null,
        dataType = 'JSON',
        cache = true,
        async = true,
        success = null
    }={}){
        // let example = new ajaxClass();//建立ajaxClass實例

        // //把私有屬性掛載到實例上
        // example.url = url;
        // example.method = type === null ? method : type;
        // example.data = data;
        // example.dataType = dataType;
        // example.cache = cache;
        // example.async = async;
        // example.success = typeof success === 'function' ? success : new Function();
        // example.isGET = /^(GET|DELETE|HEAD)$/i.test(example.method);//判斷是否是get請求
        // example.init();//執行實例上的init方法
        // return example;

        // 優化以上代碼 jquery就是這樣批量處理的
        let example = new ajaxClass(),//建立ajaxClass實例
             _this = example;
        ['url','method','data','dataType','cache','async','success'].forEach((item) => {
            if (item === 'method') {
                _this.method = type === null ? method : type;
                return;
            }
            if (item === 'success') {
                _this.success = typeof success === 'function' ? success : new Function();
                return;
            }
            _this[item] = eval(item);
        });
        _this.isGET = /^(GET|DELETE|HEAD)$/i.test(example.method);//判斷是否是get請求
        _this.init();//執行實例上的init方法
        return _this;
    };
}();
// ajax({});
複製代碼

ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script src="ajax.js"></script>
<script src="4.js"></script>
</body>
</html>
複製代碼

4.js

ajax({
    url:'temp.json',
    cache:false,
    data: {
        name:'呵呵',
        age:10
    },
    success:result => {
        console.log(result);
    }
});
複製代碼
相關文章
相關標籤/搜索