整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript封裝一個自己的Ajax并完善與拓展Ajax

          在所有主流的網站,基本上都用到了ajax技術,通過異步請求數據已經是一個很普及的實現方式。市面上主流的web前端框架也都有自己封裝的ajax,而且都是大同小異的。也就是說,Ajax這個輪子已經是多的不能再多了,那為什么我們還要自己封裝一個Ajax呢?

          想要了解一個技術或者某個功能的實現原理,只有動手實踐才能真正的了解。就如我在csdn上第一篇博客的博文描述。探索技術的路上本應該自己造輪子,即使市面上有再多的選擇,自己動手嘗試也是必要的,第一次嘗試必然會問題眾多,但你不覺得解決他是一件很有成就感的事情嗎,這樣才能帶給你更大的進步和更深刻的領悟。

          廢話不說,先來寫一個最基礎的ajax:

          [javascript] view plain copy

          1. function ajax(a){
          2. var ajax = new XMLHttpRequest();
          3. ajax.onreadystatechange = function(){
          4. if (ajax.readyState == 4 && ajax.status == 200) {
          5. a.success(JSON.stringify(ajax.responseText))
          6. }
          7. }
          8. ajax.open(a.method, a.url,true)
          9. ajax.send(a.data)
          10. }
          11. ajax({
          12. method:'get',
          13. url:'http://127.0.0.1:8081/test',
          14. success:function(res){
          15. console.log(res)
          16. }
          17. })

          一個ajax出爐了,通過調用、填寫參數即可請求到服務器。先來分析一下這個ajax的結構,可以看得出來,其實很簡單,只是new了一個XMLHttpRequest對象,然后通過onreadystatechange方法來處理返回值,現在我們只是做了一個判斷,當請求成功時就調用success方法,如果請求失敗,我們還沒有寫上去,后面我們慢慢完善這個ajax的邏輯。

          然后調用ajax的open方法,open方法里有三個參數,第一個是請求方式(如:get或post),第二個是請求的url地址,第三個是一個bool值,是否要異步請求。

          最后使用send方法帶上參數發送請求即可。

          這是,我的服務器已經收到一個請求,但他報了404錯誤,也就是找不到對應的頁面或路由,這時success方法也不會被調用執行。

          那我們再來完善一下這個新生的ajax。我們只需要在onreadystatechange方法里增加一個條件,當請求不成功時調用自身的error方法:

          [javascript] view plain copy

          1. ajax.onreadystatechange = function(){
          2. if (ajax.readyState == 4 && ajax.status == 200) {
          3. a.success(JSON.stringify(ajax.responseText))
          4. }else{
          5. a.error(ajax)
          6. }
          7. }

          這樣我們就可以在ajax請求的時候加上error方法,當ajax請求失敗的時候執行我們想要執行的操作?,F在我們拋除跨域請求的問題,當你發送post請求時,你會發現后臺接收不到傳過來的參數,調用如下:

          [javascript] view plain copy

          1. ajax({
          2. method:'get',
          3. url:'http://localhost:8081/test',
          4. data:'a=1',
          5. success:function(res){
          6. console.log(res)
          7. },
          8. error:function(res){
          9. console.log(res)
          10. }
          11. })

          后端打印一下傳過來的參數,為空。

          出現這個問題的原因主要是請求頭沒有聲明,這時候我們需要初始化聲明一下請求頭,那我們加入一行代碼:

          [javascript] view plain copy

          1. ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

          設置Conten-type為application/x-www-form-urlencoded,現在后端應該是已經可以收到參數了。那我們現在的ajax調用時實在太繁瑣,有些東西我們不想填的我們應該給他設置一個默認值,不然就會報錯。

          比如error方法、method、還有是否異步的bool值等等。那我們再加入一些默認值,現在的ajax是這樣的:

          [javascript] view plain copy

          1. function ajax(a){
          2. a.method = a.method || 'get';
          3. a.ajax = a.ajax || true;
          4. a.error = a.error || function(){
          5. console.warn('Ajax請求失敗');
          6. };
          7. var ajax = new XMLHttpRequest();
          8. ajax.onreadystatechange = function(){
          9. if (ajax.readyState == 4 && ajax.status == 200) {
          10. a.success(JSON.stringify(ajax.responseText))
          11. }else{
          12. a.error(ajax)
          13. }
          14. }
          15. ajax.open(a.method, a.url,a.ajax)
          16. ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
          17. ajax.send(a.data)
          18. }

          現在的ajax還存在一個問題,在post請求的時候,如果我們要傳參,是需要通過字符串傳參的。那這種的書寫規則并不是很友好的:

          [javascript] view plain copy

          1. a=1&b=2

          而一般框架的傳參都是通過json的格式來輸入的,我們也不能偏離大眾習慣搞獨立,當然我們也要保留字符串的傳參方式,只是要擴展功能。

          那我們需要加一個控制格式的參數,我們這里用dataType這個參數來控制傳參格式,默認是字符串格式傳參好了,可以選擇json格式進行傳參即可。如果是json格式傳參,我們需要把json轉化成字符串類型,代碼如下:

          [javascript] view plain copy

          1. a.dataType = a.dataType || 'string';
          2. var data = a.data;
          3. if (a.dataType == 'json') {
          4. var nowData = "";
          5. for (var i in data) {
          6. nowData += (nowData != ''?'&':'')+i+'='+data[i];
          7. }
          8. data = nowData;
          9. }

          這樣,我們的ajax也就可以通過json格式進行傳參了?,F在的ajax完整代碼和調用方式如下:

          [javascript] view plain copy

          1. function ajax(a){
          2. a.method = a.method || 'get';
          3. a.ajax = a.ajax || true;
          4. a.dataType = a.dataType || 'string';
          5. a.error = a.error || function(){
          6. console.warn('Ajax請求失敗');
          7. };
          8. var ajax = new XMLHttpRequest();
          9. ajax.onreadystatechange = function(){
          10. if (ajax.readyState == 4 && ajax.status == 200) {
          11. a.success(JSON.stringify(ajax.responseText))
          12. }else{
          13. a.error(ajax)
          14. }
          15. }
          16. var data = a.data;
          17. if (a.dataType == 'json') {
          18. var nowData = "";
          19. for (var i in data) {
          20. nowData += (nowData != ''?'&':'')+i+'='+data[i];
          21. }
          22. data = nowData;
          23. }
          24. ajax.open(a.method, a.url,a.ajax)
          25. ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
          26. ajax.send(data)
          27. }
          28. //調用Ajax示例
          29. ajax({
          30. method:'post',
          31. url:'http://localhost:8081/test',
          32. dataType:'json',
          33. data:{
          34. a:'1',
          35. b:'2'
          36. },
          37. success:function(res){
          38. console.log(res)
          39. }
          40. })

          現在這個Ajax基本上已經可以滿足業務上的所以需求,不過還有一點沒有實現,我們的Ajax不能設置請求頭?!為了一些特殊需求的情況下,我們還是要把這一功能加上的:

          [javascript] view plain copy

          1. if (a.requestHeader) {
          2. for (var i in a.requestHeader) {
          3. ajax.setRequestHeader(i,a.requestHeader[i])
          4. }
          5. }

          現在的完整代碼入下:

          [javascript] view plain copy

          1. function ajax(a){
          2. a.method = a.method || 'get';
          3. a.ajax = a.ajax || true;
          4. a.dataType = a.dataType || 'string';
          5. a.error = a.error || function(){
          6. console.warn('Ajax請求失敗');
          7. };
          8. var ajax = new XMLHttpRequest();
          9. ajax.onreadystatechange = function(){
          10. if (ajax.readyState == 4 && ajax.status == 200) {
          11. a.success(JSON.parse(ajax.responseText))
          12. }else if (ajax.readyState != 4 && ajax.status != 200){
          13. a.error(ajax)
          14. }
          15. }
          16. var data = a.data;
          17. if (a.dataType == 'json') {
          18. var nowData = "";
          19. for (var i in data) {
          20. nowData += (nowData != ''?'&':'')+i+'='+data[i];
          21. }
          22. data = nowData;
          23. }
          24. ajax.open(a.method, a.url,a.ajax)
          25. if (a.requestHeader) {
          26. for (var i in a.requestHeader) {
          27. ajax.setRequestHeader(i,a.requestHeader[i])
          28. }
          29. }
          30. ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
          31. ajax.send(data)
          32. }

          完整示例代碼文件:JavaScript封裝Ajax完整示例代碼

          JAX上傳的用戶體驗更好,HTML上傳用戶使用更方便一點,直接在網頁里面就能夠操作了。示例在下面提供了,是完整的源代碼,有教程,有視頻教程,基本上使用非常簡單,開發也非常簡單,有技術支持,

          網上搜了一下,基本上講這塊的文章還是很多,但是就是一個字亂,講的很混亂。也沒有提供完整的前后端示例。

          用戶上傳的文件比較大,有20G左右,直接用HTML傳的話容易失敗,服務器也容易出錯,需要分片,分塊,分割上傳。也就是將一個大的文件分成若干個小文件塊來上傳,另外就是需要實現秒傳功能和防重復功能,秒傳就是用戶如果上傳過這個文件,那么直接在數據庫中查找記錄就行了,不用再上傳一次,節省時間,實現的思路是對文件做MD5計算,將MD5值保存到數據庫,算法可以用MD5,或者CRC,或者SHA1,這個隨便哪個算法都行。

          分片還需要支持斷點續傳,現在HTML5雖然提供了信息記錄功能,但是只支持到了會話級,也就是用戶不能關閉瀏覽器,也不能清空緩存。但是有的政府單位上傳大文件,傳了一半下班了,明天繼續傳,電腦一關結果進度信息就丟失了,這個是他們的一個痛點。

          切片的話還有一點就是在服務器上合并,一個文件的所有分片數據上傳完后需要在服務器端進行合并操作。


          1.下載示例

          https://gitee.com/xproer/up6-vue-cli



          將up6組件復制到項目中

          示例中已經包含此目錄



          1.引入up6組件



          2.配置接口地址

          接口地址分別對應:文件初始化,文件數據上傳,文件進度,文件上傳完畢,文件刪除,文件夾初始化,文件夾刪除,文件列表

          參考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de



          3.處理事件



          啟動測試



          啟動成功



          效果



          數據庫

          :基本概念

          jQuery的Ajax請求實際上是封裝的一個XHLHttpRequest,從字面意思來看是,XML是一種文件格式,Http是一個網絡請求,Request最開始是用于請求XML文件的,后來不斷擴展可以請求多種類型的文件。

          XHLHttpRequest,網絡請求模塊,或者是一個瀏覽器網絡線程。用于從URL網絡上獲取數據,有了對象,就可以實現頁面的無刷新請求數據,就可以做到一個局部的更新,也可以獲取多種類型的數據(ftp、文件)。

          2:要實現和使用XMLHttpRequest

          它是一個對象,首先我們需要實例化,定義一個:

          var xhr = new XMLHttpRequest();
          

          3:初始化請求,給定一些必要的配置,給它一些property

          //Ajax請求時的參數設置
          method 請求方式
          url 請求地址
          async 是否異步
          user 用戶名
          password 密碼
          ?
          xhr.open(method,url,async,user,password);
          

          4:發送請求(encodeURLComponent)

          xhr.send(data);
          等待接收
          

          5:接收網絡請求返回

          一般有如下屬性:

          • responseText,請求返回的數據內容,可以是一段文本,是一段二進制或者是一個json
          • responseXML

          是一個文件,如果響應頭內容是text/xml,這個屬性將保留響應數據的XML、DOM文檔。

          • status,響應的HTTP狀態,如 200(正常,200-300之間都表示成功) 304(使用緩存) 404(沒找到) 500(服務器內部錯誤)等
          • statusText,HTTP狀態說明
          • readyStatus,請求/響應過程的當前活動階段,一共有5個值:0(未被調用open),1(已被調用open但未發送),2(已調用send),3(已接收到請求返回的數據),4(請求已完成)。
          • timeout,設置請求超時時間
          xhr.onreadystatechange = () => {
           if (xhr.readyStatus === 4) {
           /* HTTP 狀態在 200-300 之間表示請求成功 */
           /* HTTP 狀態為 304 表示請求內容未發生改變,可直接從緩存中讀取 */
           if (xhr.status >= 200 &&
           xhr.status < 300 ||
           xhr.status == 304) {
           console.log('請求成功', xhr.responseText)
           }
           }
          }
          

          6:封裝(promise)

          function ajax (options) {
           /* 獲取請求地址 */
           let url = options.url;
           /* 獲取請求方法 */
           const method = options.method.toLocaleLowerCase() || 'get';
           /* 默認異步 */
           const async = options.async != false;
           /* 獲取請求request數據 */
           const data = options.data;
           /* 實例化XMLHttpRequest */
           const xhr = new XMLHttpRequest();
           /* 設置超時時間 */
           if (options.timeout && options.timeout > 0) {
           xhr.timeout = options.timeout
           }
          ?
           return new Promise ( (resolve, reject) => {
           /* 添加超時回調 */
           xhr.ontimeout = () => reject && reject('請求超時');
           /* 成功回調 */
           xhr.onreadystatechange = () => {
           if (xhr.readyState == 4) {
           if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
           resolve && resolve(xhr.responseText);
           } else {
           reject && reject();
           }
           }
           }
          ?
           /* 失敗回調 */
           xhr.onerror = err => reject && reject(err);
          ?
           /* 拼接參數 */
           let paramArr = [];
           let encodeData;
           if (data instanceof Object) {
           for (let key in data) {
           paramArr.push( encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) );
           }
           encodeData = paramArr.join('&');
           }
          ?
           /* get請求 */
           if (method === 'get') {
           const index = url.indexOf('?')
           if (index === -1) url += '?'
           else if (index !== url.length -1) url += '&'
           url += encodeData
           }
          ?
           /* 初始化請求 */
           xhr.open(method, url, async);
          ?
           /* get直接發送拼接的URL */
           if (method === 'get') xhr.send(null);
          ?
           if (method === 'post') {
           xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8')
           xhr.send(encodeData)
           }
           })
          }
          

          總結:關于網絡請求,一般常用的有四種:

          一個是get,獲取網絡資源

          然后是post,一般用于提交數據,提交數據的參數是放在請求的body里面的

          delete,刪除

          put,標準的一個修改

          關于Http的簡單請求和非簡單請求或者是跨域,在跨域時由于瀏覽器的安全機制,涉及到一個問題關于在Ajax請求 ,是在請求之后還是請求之前判斷跨域,這時候就需要了解一下簡單請求和復雜請求。

          簡單請求是先把資源請求回來,然后再去判斷是否跨域。如果是一個復雜請求,瀏覽器會先去發送一個嗅探或者是欲請求(一般是一個option),先判斷是否跨域,如果不是跨域那就執行,如果是跨域那就直接不請求了。一般來講,如果get不修改它的Content-Type,那么基本上都是簡單請求。post如果采用www-form的形式,也是一個簡單請求。

          這篇文章主要是分享了Javascript中XMLHttpRequest對象的基本屬性和方法, 從實例化、初始化、發送和接受四個階段完成了Ajax網絡請求核心內容封裝。


          主站蜘蛛池模板: 亚洲午夜一区二区电影院| 久久久精品一区二区三区| 日本一道高清一区二区三区| 在线观看国产一区二三区| 亚洲一区无码精品色| 精品国产免费一区二区三区香蕉| 国产精品高清一区二区三区不卡 | 国产成人一区二区三区免费视频 | 一区二区无码免费视频网站| 国产精品成人免费一区二区| 国产一区中文字幕在线观看 | 大伊香蕉精品一区视频在线 | 无码国产精品一区二区免费vr | 亚洲av午夜福利精品一区| 亚洲熟妇AV一区二区三区浪潮 | 日韩aⅴ人妻无码一区二区| 国产精品一区二区不卡| 亚洲国产精品一区| 一区二区三区视频在线| 久久青草精品一区二区三区| 一区二区三区日韩| 国产高清视频一区三区| 国产亚洲综合一区柠檬导航| 国产精品区AV一区二区| 精品亚洲一区二区三区在线观看| 中文字幕国产一区| 亚洲一区二区三区免费观看 | 国产精品揄拍一区二区| 亚洲天堂一区二区| 国产精品视频一区麻豆| 一区二区传媒有限公司| 成人免费视频一区| 国产一区三区三区| 成人区精品一区二区不卡亚洲| 中文字幕AV一区二区三区人妻少妇| 国产伦精品一区二区三区四区 | 搡老熟女老女人一区二区| 国产精品亚洲高清一区二区| 亚洲av成人一区二区三区在线播放 | 曰韩精品无码一区二区三区| 美日韩一区二区三区|