需求場景:藉助 ajaxTransport 來自定義擴充套件功能。
-
專案需求:jQuery 版本: 1.10.2,錯誤打點,發起 jsonp 請求發生錯誤的時候前端需要向打點地址傳送一個請求。
-
簡單演示:
測試程式碼:$.ajax(`http://google.com/a.js`, { type: `GET`, dataType: `jsonp`, success: function(success, statusText, jqXHR){ console.log(`jsonp request success`); }, error: function(jqXHR, statusText, error){ console.log(`jsonp error`); } }); 由於 1.10.2 版本的 jquery 並沒有對建立的 script 監聽錯誤事件,故無法呼叫 error 方法,故無法進一步將前端資訊錯誤上報
解決方案:
$.ajaxTransport(`+script`, function(s){ // This transport only deals with cross domain requests var script, head = document.head || $(`head`)[0] || document.documentElement; return { send: function(_, callback) { script = document.createElement(`script`); script.async = true; if(s.scriptCharset){ script.charset = s.scriptCharset; } script.src = s.url; // Handle error script.onerror = function(err){ // Handle memory lead in IE script.onload = script.onreadystatechange = null; script.onerror = null; // Remove the script if(script.parentNode){ script.parentnode.removeChild(script); } // Dereference the script script = null; if(err.type === `error`){ callback(404, err.type); } } // Attach handlers for all browsers script.onload = script.onreadystatechange = function(_, isAbort){ if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState)){ // Handle memeory leak in IE script.onload = script.onreadystatechange = null; // Remove the script if(script.parentNode){ script.parentNode.removeChild(script); } // Dereference the script script = null; // Callback if not abort if(!isAbort){ callback(200, `success`); } } }; // Cicumvent IE6 bugs with base elements (#2709 and #4378) by prepending // Use native DOM manipulation to avoid our domManip AJAX trickery head.insertBefore(script, head.firstChild); }, abort: function(){ if(script){ script.onload(undefined, true); } } }; });
需求場景:藉助 ajaxSetup 新增 dataType.
-
專案需求:需要從伺服器獲取 yaml 檔案,然後解析該檔案
-
簡單演示:
解決方案:function parseYaml(text){ console.log(`You are parsing yaml file!`); return `yaml` + text + `yaml`; } $.ajaxSetup({ accepts: { yaml: `application/x-yaml, text/yaml` }, contents: { yaml: /yaml/ }, converters: { `text yaml`: function(text){ return parseYaml(text); } } });
測試程式碼:
// 傳送 dataType 為 yaml 的請求 $.ajax({ url: `http://google.com/helloworld.yaml`, dataType: `yaml`, success: function(data){ console.log(data); } });
需求場景:藉助 ajaxPrefilter 來自定義擴充套件功能。
-
專案需求:防止 ajax 請求的重複提交
-
簡單演示:
解決方案:
var pendingRequests = {};function storePendingRequest(key, jqXHR){
pendingRequests[key] = true; jqXHR.pendingRequestKey = key;
}
function generatePendingRequestKey(options){
return (options.type + options.url + options.dataType).toLowerCase().replace(/[^a-z0-9]/g, ``);
}
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {// 不重複傳送相同請求 var key = generatePendingRequestKey(options); if (!pendingRequests[key]) { storePendingRequest(key, jqXHR); } else { // or do other jqXHR.abort(); } var complete = options.complete; options.complete = function(jqXHR, textStatus) { // clear from pending requests pendingRequests[jqXHR.pendingRequestKey] = null; if ($.isFunction(complete)) { complete.apply(this, arguments); } };
});
測試程式碼:
for(var i = 0; i < 10; i++){var j = 0; $.ajax({ url: `http://js.passport.qihucdn.com/5.0.2.js`, type: `GET`, dataType: `HTML`, complete: function(){ console.log(`complete:` + j++); } });
}