需求场景:借助 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++); } });
}