距離上一次博客大概好多好多時間了,感受再不搞點東西出來,感受就廢了的感受。這段時間回老家學習駕照,修養,而後7月底來上海求職(面了4家,拿了3家office),而後入職同程旅遊,項目趕進度等等一系列的緣由,致使沒有太多時間去搞東西。感受虧欠了好多,因此此次一次性補上。廢話很少說了,咱們直接進入主題。前端
介紹此次講解的庫的更新:vue
ajax全局配置git
對於這個東西,相信你們都頗有感觸,在咱們開發中的場景也不少,例如github
因此有了這個玩意,我只是定義一些經常使用的基礎的,其餘的你們能夠根據本身業務需求進行拓展和改造,而後push一個分支,我會討論協商以後採納的。代碼以下:web
PS:這公共參數玩意我忘了去限制了,若是傳輸和其餘初始化參數同樣的會覆蓋的,下個版本進行改進,見諒。ajax
//經過拋出的config方法設置全局參數 ajax.config({ baseURL: '', //通用url前綴 requestHeader: {}, //公共頭部 publicData: {}, //公共參數 timeout: 5000, //超時時間 responseType: 'json', //response參數類型,默認'json' contentType: '', //請求參數類型(''、'json'、'form') withCredentials: true, //是否啓用跨域憑證傳輸 isOpenErr: true, //是否開啓瀏覽器錯誤回收 errURL: '', //瀏覽器錯誤回收地址 //請求發送前對數據進行處理 transformRequest: function (data) { return data; }, //獲得正確請求後作的處理 transformResponse: function (data) { return data; }, //請求錯誤處理 errorEvent: function (x, xx, xxx) { }, //請求超時處理 timeoutEvent: function (code, e) { } })
請求參數的拓展(增長json)和重構優化npm
在以前寫的庫中,只針對請求作了通用的請求和form請求,可是針對經常使用的請求類型json格式沒有支持,因此此次將這個參數進行支持(主要咱們項目中用到了,可是我寫的庫沒有,因此支持)json
其次所謂的重構優化,只是感受以前的代碼太TM挫了。不利於拓展和維護,因此此次將它進行優化。後端
//參數處理 if (ajaxSetting.data) { //有數據作參數處理 switch (ajaxSetting.contentType) { case '': //通用請求 tool.each(tool.MergeObject(ajaxSetting.data, ajaxSetting.publicData), function (item, index) { sendData += (index + "=" + item + "&") }); sendData = sendData.slice(0, -1); ajaxSetting.requestHeader['Content-Type'] = 'application/x-www-form-urlencoded' break case 'json': //json請求 sendData = JSON.stringify(tool.MergeObject(ajaxSetting.data, ajaxSetting.publicData)) ajaxSetting.requestHeader['Content-Type'] = 'application/json' break case 'form': //form請求 if (!tool.isEmptyObject(ajaxSetting.publicData)) { tool.each(ajaxSetting.publicData, function (item, index) { ajaxSetting.data.append(index, item) }) } sendData = ajaxSetting.data break } //請求前處理參數 sendData = ajaxSetting.transformRequest(sendData) //判斷請求類型 if (ajaxSetting.type === 'get') { xhr.open(ajaxSetting.type, tool.checkRealUrl(ajaxSetting) + '?' + sendData, ajaxSetting.async) } else { xhr.open(ajaxSetting.type, tool.checkRealUrl(ajaxSetting), ajaxSetting.async) } } else { xhr.open(ajaxSetting.type, ajaxSetting.baseURL + ajaxSetting.url, ajaxSetting.async) }
初始化參數類型檢查api
初始化參數檢查這個功能主要在每一個請求中,可能不是定義的參數都想傳輸的,好比我作瀏覽器錯誤回收的時候,我只想將這個錯誤的信息發送到錯誤回收地址,我不須要作任何處理,只須要發出去,無論成不成功。因此我只有post2個參數,地址和錯誤信息。若是不作參數檢查,合併參數的時候,會把undefind合併到初始化參數中,致使程序宕機,容錯性、健壯性特別差,這樣的程序當雖然是咱們都不想看到和去寫的,因此作了這塊。代碼以下:
類型檢查代碼:
//類型判斷 is: (function checkType() { var is = { types: ["Array", "Boolean", "Date", "Number", "Object", "RegExp", "String", "Window", "HTMLDocument", "function", "FormData"] }; for (var i = 0, c; c = is.types[i++];) { is[c] = (function (type) { return function (obj) { var temp; if (type === "function") { temp = typeof obj == type } else { temp = Object.prototype.toString.call(obj) == "[object " + type + "]"; } return temp; } })(c); } ; return is; })(),
批量處理代碼:
//批量檢查數據類型 checkDataTypeBatch: function (obj, objType) { var temp = true; tool.each(obj, function (value, key) { var typeName = objType[key], tempOutput; if (tool.is.Array(typeName)) { tool.each(typeName, function (item) { tempOutput = tempOutput || tool.is[item](value); }) } else { tempOutput = tool.is[typeName](value) } //若是格式不對,將錯誤數據恢復到初始化數據 if (!tempOutput) { obj[key] = initParam[key] } }) return temp; },
初始化數據和初始化數據類型
//默認參數 var initParam = { url: "", type: "", baseURL: '', data: {}, async: true, requestHeader: {}, publicData: {}, timeout: 5000, responseType: 'json', contentType: '', withCredentials: false, isOpenErr: false, errURL: '', transformRequest: function (data) { return data; }, transformResponse: function (data) { return data; }, successEvent: function (data) { }, errorEvent: function (x, xx, xxx) { }, timeoutEvent: function (code, e) { } }; //初始化參數固定類型檢查 var initParamType = { url: "String", type: "String", baseURL: 'String', data: ['Object', 'FormData'], async: 'Boolean', requestHeader: 'Object', publicData: 'Object', timeout: 'Number', responseType: 'String', contentType: 'String', withCredentials: 'Boolean', isOpenErr: 'Boolean', errURL: 'String', transformRequest: 'function', transformResponse: 'function', successEvent: 'function', errorEvent: 'function', timeoutEvent: 'function' };
PS:可能不會將全部的全部的都考慮進去,可是這些已經能完成我暫時的需求了,若是想對這個方法作補充的,能夠直接郵件或者github提交分支,而後驗證討論完善會合併到master上的
瀏覽器錯誤回收機制
瀏覽器錯誤回收這個概念,通常的公司是不會作的,只有那種針對普遍用戶,普遍瀏覽器兼容性的產品纔會作。由於可能在主流瀏覽器上會出現問題,畢竟將市面上全部瀏覽器都作測試,對於公司的測試人員來講都是一個極大的工做量,因此相對來講確定有不少忽略的,可是對於公司來講,每一個客戶都是一種珍貴的資源,在不破壞主流的基礎上仍是須要兼容的。因此回收這些錯誤,才顯得重要。
其次,還有更重要的一點,對於線上的bug和隱形的bug,永遠是重大的生產問題,在大公司會被問責的。因此瀏覽器錯誤蒐集才顯得更加劇要,在沒有被擴大以前能及時回收到纔是最重要的。由於我曾在極客頭條這個網站遇到過,他們更新版本後登陸接口請求參數變化了,可是對於前端來講並無響應處理,致使登陸不上。這樣的問題,若是發生在淘寶上的話,一個部門會直接被問責的。
so,有這個想法就作了,並且我這主要寫了前端通訊,因此順便加進去了。(PS:如今只作了瀏覽器的錯誤蒐集處理,對於ajax的錯誤處理沒有監控,下個版本補上。畢竟接口的404等錯誤,瀏覽器onerror是不會觸發的)
//監控瀏覽器的錯誤日誌 setOnerror: function () { window.onerror = function (errInfo, errUrl, errLine) { tempObj.post(initParam.errURL, { errInfo: errInfo, //錯誤信息 errUrl: errUrl, //錯誤地址 errLine: errLine, //錯誤行號 Browser: navigator.userAgent //瀏覽器版本 }) } },
so,看完了是否是很簡單,其實就是這麼簡單,ajax接口錯誤監控暫時沒有最好的方案,由於在ajax考慮到瀏覽器的兼容性錯誤地方不一樣,並且要將錯誤回收地址的錯誤忽略掉,並且要考慮何時切入監控這個點最好等等,並且要配置進主流程能動態配置,哎不說了,下期吧。順便下期將前端接口容錯機制加上去,好比監控到40四、50三、403等錯誤信息,前端接口自動將請求地址切換到備用地址,保證程序的健壯性。
增長ajax請求blob(二進制)類型
這個功能是以前想作的,不知道有沒有真實場景進行使用的。我作的測試只是針對一個圖片作的測試,請求一個二進制圖片,而後反顯。可是後期的場景可能比較重要,瀏覽器經過ajax流式下載文件等等,這個功能待定吧。
//獲取blob數據集代碼 obtainBlob: function (type, url, data, successEvent, errorEvent, timeoutEvent) { var ajaxParam = { type: type, url: url, data: data, responseType: 'blob', successEvent: successEvent, errorEvent: errorEvent, timeoutEvent: timeoutEvent }; ajax.common(ajaxParam); },
//test ObtainBlob(確保地址正確)測試代碼 ajax.obtainBlob("get","http://10.73.1.198:9999/Scripts/lei.jpg", '', function (getData) { var reader = new FileReader(); reader.readAsDataURL(getData) reader.onload = function (e) { document.querySelector("#imgICO").setAttribute('src',e.target.result) } console.log(typeof getData); });
關於跨域的問題支持
跨域隔離:瀏覽器的core中,針對跨域爲了安全作了限制,在跨域的時候將不會把cookie等憑證的數據進行服務器和客戶端之間回傳。因此,爲了更快的請求靜態資源,能夠將本項目中的靜態資源放到不一樣的域中,這樣進行跨域了,因此傳輸的請求比較小,速度也更快
可是,在多項目中,確定會和其餘項目組合做,so,有時候會須要這些憑證作一些自動登陸、身份驗證等功能。因此會須要進行憑證傳輸。
在XMLHttprequest中有個屬性withCredentials,這個屬性控制前端是否傳輸憑證信息(全局配置中已加),固然服務器也須要設置跨域請求的頭部:"Access-Control-Allow-Credentials: true"。這樣就能夠愉快的玩耍啦
npm打包發佈
這是最後一個了,也是完成一個關注的人的建議。在以前的博客中,有個朋友進行建議的,因此我進行了搜索、改造、發佈、測試。因此時間週期有點長了。
npm:ajax-js
安裝:npm i ajax-js / yarn add ajax-js
使用:在頁面中引入,而後使用
<template> <div id="app"> select file:<input type="file" id="file1" accept="*"/><br/> <input type="button" id="upload" value="upload"/> <input type="button" id="uploadBig" value="uploadBig"/> <img id="imgICO"/> </div> </template> <script> import _ajax from 'ajax-js' export default { name: 'app', created(){ _ajax.get('http://10.73.1.198:9999/api/cores/getAjax/',{name:'get請求成功',age:11},function (res) { console.log(res.name) }) //test post _ajax.post("http://10.73.1.198:9999/api/cores/postAjax/",{name:'post請求測試成功',age:1},function(getData){ console.log(getData.name); }); // var formData = new FormData(); formData.append("name", "post Form請求測試成功"); formData.append("age", 11); _ajax.postFormData("http://10.73.1.198:9999/api/cores/postForm/",formData,function (res) { console.log(res.name) }) // //test post // _ajax.postJSON("http://10.73.1.198:9999/api/cores/postAjax/",{name:'postJSON請求測試成功',age:1},function(getData){ // console.log(getData.name); // }); //test ObtainBlob(確保地址正確) // ajax.obtainBlob("get","http://10.73.1.198:9999/Scripts/lei.jpg", '', function (getData) { // var reader = new FileReader(); // reader.readAsDataURL(getData) // reader.onload = function (e) { // document.querySelector("#imgICO").setAttribute('src',e.target.result) // } // console.log(typeof getData); // }); //promise通常測試 _ajax.promiseAjax('http://10.73.1.198:9999/api/cores/postReqSleep/',{name:'promise高延遲接口測試1',age:123}) .then(function (res) { console.log(res.name) return _ajax.promiseAjax('http://10.73.1.198:9999/api/cores/postAjax/',{name:'promise通常接口測試2',age:456}) }).then(function (res) { console.log(res.name) }) // //併發promise測試 _ajax.promiseAjax('http://10.73.1.198:9999/api/cores/postAjax/',{name:'promise併發接口測試3',age:123456}) .then(function (res) { console.log(res.name) return _ajax.promiseAjax('http://10.73.1.198:9999/api/cores/postReqSleep/',{name:'promise併發高延遲接口測試4',age:456789}) }).then(function (res) { console.log(res.name) }) // var longTemp = 0; _ajax.longPolling('post','http://10.73.1.198:9999/api/cores/postAjax/',{name:'輪詢測試',age:123456},function (res,that) { console.log(res.name+longTemp) longTemp+=1; if (longTemp === 10){ that.stop = true; } },1000) // }, mounted(){ //test post _ajax.postJSON("api/postAjax",{name:'postJSON請求測試成功',age:1},function(getData){ console.log(getData.name); }); //test uploadFile document.querySelector("#upload").onclick = function () { var temp = _ajax.upload("http://10.73.1.198:9999/api/cores/upload/","#file1",1024*1024,['image/png'],function(x){ }) console.log(temp); }; // // //test uploadFile document.querySelector("#uploadBig").onclick = function () { JSON.parse('') // var temp = ajax.upload_big("api/cores/uploadBig/","#file1",1024*1024,"*",function(x){},function(count,all){console.log("當前傳輸進度:"+count+"/"+all);}) var temp = _ajax.upload_big("http://10.73.1.198:9999/api/cores/uploadBig/","#file1",1024*1024,"*",function(x){},function(count,all){console.log("當前傳輸進度:"+count+"/"+all);}) console.log(temp); }; } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
PS:這個是在vue中的進行測試的。測試結果以下。
如下爲不用npm安裝的測試,測試頁面在github上,後端接口用的.net,也在上面,看圖:
看通常頁面的測試結果
錯誤蒐集接口查看
好啦,這個版本已經發布好了,有新的需求就籌劃下個版本的東西啦。最近在研究SSE,也就是前端的服務器推送玩意,準備這段時間總結出一套東西,順便針對這個技術自己的一些技術侷限設計解決一些方案,好比SSE只能默認推送全部人,能夠設計針對單我的去推送等等
代碼已集成github和npm打包:https://github.com/GerryIsWarrior/ajax / npm i ajax-js 點顆星星是我最大的鼓勵,有什麼問題能夠博客、郵箱、github上留言