Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产亚洲一区二区三区在线,日本视频免费在线观看,亚洲国产精品网站久久

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JavaScript封裝一個(gè)自己的Ajax并完善與拓展Ajax

          在所有主流的網(wǎng)站,基本上都用到了ajax技術(shù),通過(guò)異步請(qǐng)求數(shù)據(jù)已經(jīng)是一個(gè)很普及的實(shí)現(xiàn)方式。市面上主流的web前端框架也都有自己封裝的ajax,而且都是大同小異的。也就是說(shuō),Ajax這個(gè)輪子已經(jīng)是多的不能再多了,那為什么我們還要自己封裝一個(gè)Ajax呢?

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

          廢話不說(shuō),先來(lái)寫(xiě)一個(gè)最基礎(chǔ)的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. })

          一個(gè)ajax出爐了,通過(guò)調(diào)用、填寫(xiě)參數(shù)即可請(qǐng)求到服務(wù)器。先來(lái)分析一下這個(gè)ajax的結(jié)構(gòu),可以看得出來(lái),其實(shí)很簡(jiǎn)單,只是new了一個(gè)XMLHttpRequest對(duì)象,然后通過(guò)onreadystatechange方法來(lái)處理返回值,現(xiàn)在我們只是做了一個(gè)判斷,當(dāng)請(qǐng)求成功時(shí)就調(diào)用success方法,如果請(qǐng)求失敗,我們還沒(méi)有寫(xiě)上去,后面我們慢慢完善這個(gè)ajax的邏輯。

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

          最后使用send方法帶上參數(shù)發(fā)送請(qǐng)求即可。

          這是,我的服務(wù)器已經(jīng)收到一個(gè)請(qǐng)求,但他報(bào)了404錯(cuò)誤,也就是找不到對(duì)應(yīng)的頁(yè)面或路由,這時(shí)success方法也不會(huì)被調(diào)用執(zhí)行。

          那我們?cè)賮?lái)完善一下這個(gè)新生的ajax。我們只需要在onreadystatechange方法里增加一個(gè)條件,當(dāng)請(qǐng)求不成功時(shí)調(diào)用自身的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請(qǐng)求的時(shí)候加上error方法,當(dāng)ajax請(qǐng)求失敗的時(shí)候執(zhí)行我們想要執(zhí)行的操作。現(xiàn)在我們拋除跨域請(qǐng)求的問(wèn)題,當(dāng)你發(fā)送post請(qǐng)求時(shí),你會(huì)發(fā)現(xiàn)后臺(tái)接收不到傳過(guò)來(lái)的參數(shù),調(diào)用如下:

          [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. })

          后端打印一下傳過(guò)來(lái)的參數(shù),為空。

          出現(xiàn)這個(gè)問(wèn)題的原因主要是請(qǐng)求頭沒(méi)有聲明,這時(shí)候我們需要初始化聲明一下請(qǐng)求頭,那我們加入一行代碼:

          [javascript] view plain copy

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

          設(shè)置Conten-type為application/x-www-form-urlencoded,現(xiàn)在后端應(yīng)該是已經(jīng)可以收到參數(shù)了。那我們現(xiàn)在的ajax調(diào)用時(shí)實(shí)在太繁瑣,有些東西我們不想填的我們應(yīng)該給他設(shè)置一個(gè)默認(rèn)值,不然就會(huì)報(bào)錯(cuò)。

          比如error方法、method、還有是否異步的bool值等等。那我們?cè)偌尤胍恍┠J(rèn)值,現(xiàn)在的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請(qǐng)求失敗');
          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. }

          現(xiàn)在的ajax還存在一個(gè)問(wèn)題,在post請(qǐng)求的時(shí)候,如果我們要傳參,是需要通過(guò)字符串傳參的。那這種的書(shū)寫(xiě)規(guī)則并不是很友好的:

          [javascript] view plain copy

          1. a=1&b=2

          而一般框架的傳參都是通過(guò)json的格式來(lái)輸入的,我們也不能偏離大眾習(xí)慣搞獨(dú)立,當(dāng)然我們也要保留字符串的傳參方式,只是要擴(kuò)展功能。

          那我們需要加一個(gè)控制格式的參數(shù),我們這里用dataType這個(gè)參數(shù)來(lái)控制傳參格式,默認(rèn)是字符串格式傳參好了,可以選擇json格式進(jìn)行傳參即可。如果是json格式傳參,我們需要把json轉(zhuǎn)化成字符串類(lèi)型,代碼如下:

          [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也就可以通過(guò)json格式進(jìn)行傳參了。現(xiàn)在的ajax完整代碼和調(diào)用方式如下:

          [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請(qǐng)求失敗');
          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. //調(diào)用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. })

          現(xiàn)在這個(gè)Ajax基本上已經(jīng)可以滿足業(yè)務(wù)上的所以需求,不過(guò)還有一點(diǎn)沒(méi)有實(shí)現(xiàn),我們的Ajax不能設(shè)置請(qǐng)求頭?!為了一些特殊需求的情況下,我們還是要把這一功能加上的:

          [javascript] view plain copy

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

          現(xiàn)在的完整代碼入下:

          [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請(qǐng)求失敗');
          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上傳的用戶體驗(yàn)更好,HTML上傳用戶使用更方便一點(diǎn),直接在網(wǎng)頁(yè)里面就能夠操作了。示例在下面提供了,是完整的源代碼,有教程,有視頻教程,基本上使用非常簡(jiǎn)單,開(kāi)發(fā)也非常簡(jiǎn)單,有技術(shù)支持,

          網(wǎng)上搜了一下,基本上講這塊的文章還是很多,但是就是一個(gè)字亂,講的很混亂。也沒(méi)有提供完整的前后端示例。

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

          分片還需要支持?jǐn)帱c(diǎn)續(xù)傳,現(xiàn)在HTML5雖然提供了信息記錄功能,但是只支持到了會(huì)話級(jí),也就是用戶不能關(guān)閉瀏覽器,也不能清空緩存。但是有的政府單位上傳大文件,傳了一半下班了,明天繼續(xù)傳,電腦一關(guān)結(jié)果進(jìn)度信息就丟失了,這個(gè)是他們的一個(gè)痛點(diǎn)。

          切片的話還有一點(diǎn)就是在服務(wù)器上合并,一個(gè)文件的所有分片數(shù)據(jù)上傳完后需要在服務(wù)器端進(jìn)行合并操作。


          1.下載示例

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



          將up6組件復(fù)制到項(xiàng)目中

          示例中已經(jīng)包含此目錄



          1.引入up6組件



          2.配置接口地址

          接口地址分別對(duì)應(yīng):文件初始化,文件數(shù)據(jù)上傳,文件進(jìn)度,文件上傳完畢,文件刪除,文件夾初始化,文件夾刪除,文件列表

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



          3.處理事件



          啟動(dòng)測(cè)試



          啟動(dòng)成功



          效果



          數(shù)據(jù)庫(kù)

          :基本概念

          jQuery的Ajax請(qǐng)求實(shí)際上是封裝的一個(gè)XHLHttpRequest,從字面意思來(lái)看是,XML是一種文件格式,Http是一個(gè)網(wǎng)絡(luò)請(qǐng)求,Request最開(kāi)始是用于請(qǐng)求XML文件的,后來(lái)不斷擴(kuò)展可以請(qǐng)求多種類(lèi)型的文件。

          XHLHttpRequest,網(wǎng)絡(luò)請(qǐng)求模塊,或者是一個(gè)瀏覽器網(wǎng)絡(luò)線程。用于從URL網(wǎng)絡(luò)上獲取數(shù)據(jù),有了對(duì)象,就可以實(shí)現(xiàn)頁(yè)面的無(wú)刷新請(qǐng)求數(shù)據(jù),就可以做到一個(gè)局部的更新,也可以獲取多種類(lèi)型的數(shù)據(jù)(ftp、文件)。

          2:要實(shí)現(xiàn)和使用XMLHttpRequest

          它是一個(gè)對(duì)象,首先我們需要實(shí)例化,定義一個(gè):

          var xhr = new XMLHttpRequest();
          

          3:初始化請(qǐng)求,給定一些必要的配置,給它一些property

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

          4:發(fā)送請(qǐng)求(encodeURLComponent)

          xhr.send(data);
          等待接收
          

          5:接收網(wǎng)絡(luò)請(qǐng)求返回

          一般有如下屬性:

          • responseText,請(qǐng)求返回的數(shù)據(jù)內(nèi)容,可以是一段文本,是一段二進(jìn)制或者是一個(gè)json
          • responseXML

          是一個(gè)文件,如果響應(yīng)頭內(nèi)容是text/xml,這個(gè)屬性將保留響應(yīng)數(shù)據(jù)的XML、DOM文檔。

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

          6:封裝(promise)

          function ajax (options) {
           /* 獲取請(qǐng)求地址 */
           let url = options.url;
           /* 獲取請(qǐng)求方法 */
           const method = options.method.toLocaleLowerCase() || 'get';
           /* 默認(rèn)異步 */
           const async = options.async != false;
           /* 獲取請(qǐng)求request數(shù)據(jù) */
           const data = options.data;
           /* 實(shí)例化XMLHttpRequest */
           const xhr = new XMLHttpRequest();
           /* 設(shè)置超時(shí)時(shí)間 */
           if (options.timeout && options.timeout > 0) {
           xhr.timeout = options.timeout
           }
          ?
           return new Promise ( (resolve, reject) => {
           /* 添加超時(shí)回調(diào) */
           xhr.ontimeout = () => reject && reject('請(qǐng)求超時(shí)');
           /* 成功回調(diào) */
           xhr.onreadystatechange = () => {
           if (xhr.readyState == 4) {
           if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
           resolve && resolve(xhr.responseText);
           } else {
           reject && reject();
           }
           }
           }
          ?
           /* 失敗回調(diào) */
           xhr.onerror = err => reject && reject(err);
          ?
           /* 拼接參數(shù) */
           let paramArr = [];
           let encodeData;
           if (data instanceof Object) {
           for (let key in data) {
           paramArr.push( encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) );
           }
           encodeData = paramArr.join('&');
           }
          ?
           /* get請(qǐng)求 */
           if (method === 'get') {
           const index = url.indexOf('?')
           if (index === -1) url += '?'
           else if (index !== url.length -1) url += '&'
           url += encodeData
           }
          ?
           /* 初始化請(qǐng)求 */
           xhr.open(method, url, async);
          ?
           /* get直接發(fā)送拼接的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)
           }
           })
          }
          

          總結(jié):關(guān)于網(wǎng)絡(luò)請(qǐng)求,一般常用的有四種:

          一個(gè)是get,獲取網(wǎng)絡(luò)資源

          然后是post,一般用于提交數(shù)據(jù),提交數(shù)據(jù)的參數(shù)是放在請(qǐng)求的body里面的

          delete,刪除

          put,標(biāo)準(zhǔn)的一個(gè)修改

          關(guān)于Http的簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求或者是跨域,在跨域時(shí)由于瀏覽器的安全機(jī)制,涉及到一個(gè)問(wèn)題關(guān)于在Ajax請(qǐng)求 ,是在請(qǐng)求之后還是請(qǐng)求之前判斷跨域,這時(shí)候就需要了解一下簡(jiǎn)單請(qǐng)求和復(fù)雜請(qǐng)求。

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

          這篇文章主要是分享了Javascript中XMLHttpRequest對(duì)象的基本屬性和方法, 從實(shí)例化、初始化、發(fā)送和接受四個(gè)階段完成了Ajax網(wǎng)絡(luò)請(qǐng)求核心內(nèi)容封裝。


          主站蜘蛛池模板: 一区二区不卡久久精品| 亚洲视频一区二区在线观看| 日本精品一区二区三区四区| 国产在线精品一区二区在线观看| 无码人妻精品一区二区三区蜜桃| 国产短视频精品一区二区三区| 国产精品99无码一区二区| 国产品无码一区二区三区在线| 嫩B人妻精品一区二区三区| 美女视频免费看一区二区| 无码精品一区二区三区| 亚洲AV福利天堂一区二区三| 亚洲永久无码3D动漫一区| 日本高清成本人视频一区| 精品人妻少妇一区二区| 亚洲男人的天堂一区二区| 一区二区免费电影| 日本免费精品一区二区三区| 精品一区二区三区视频在线观看| 欧美日本精品一区二区三区 | 国产精品亚洲不卡一区二区三区| 在线免费一区二区| 精品一区二区91| 亚洲Aⅴ无码一区二区二三区软件 亚洲AⅤ视频一区二区三区 | 尤物精品视频一区二区三区| 色综合久久一区二区三区| 日韩久久精品一区二区三区| 在线观看精品视频一区二区三区| 九九无码人妻一区二区三区| 国产精品无码一区二区三区在| 国产精品第一区揄拍无码| 一区二区三区视频免费观看| 国产一区二区视频在线观看| 国产精品成人国产乱一区| 国产一区二区三区在线2021| 国产99久久精品一区二区| 日韩福利视频一区| 韩日午夜在线资源一区二区| 搡老熟女老女人一区二区| 无码一区二区三区亚洲人妻| 狠狠色婷婷久久一区二区|