惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
Google DeepMind News
Google DeepMind News
腾讯CDC
G
Google Developers Blog
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
美团技术团队
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志

博客园 - 深蓝--广州

AngularJs angular.identity和angular.noop详解 css中clearfix清除浮动的用法及其原理示例介绍 opacity与RGBA透明的区别 CSS3 Gradient javascript语言精粹 严格模式认识 Promise与Defer认识 使用javascript打开一个新页而不被浏览器屏蔽 关于浏览器缓存 ie6下js更新元素display:block后,仍然不显示的hack办法 移动端开发问题整理 修改input的type属性 transform:rotate在手机上显示有锯齿的解决方案 javascript钩子机制 jQuery.validate 常用方法及注意问题 SWFObject推出2使用示例 .NET种Json时对单引号和特殊字符串的处理 自定义枚举类型注释属性,并在程序中获取 Python Win32 Extensions
jQuery jsonp无法捕获404、500状态错误
深蓝--广州 · 2015-08-22 · via 博客园 - 深蓝--广州

今天同事在用jQuery的ajax方法去调用一个jsonp的api时,服务端出现了500错误,但是前端的jQuery代码却没有触发error事件,代码如下:

$.ajax({
        url: 'http://ptres.37.com/js/sq/modules/base44.js',
        type: 'GET',
        dataType: 'jsonp'
    })
    .done(function() {
        console.log("success");
    })
    .fail(function() {
        console.log("error");
    }).always(function(){
        console.log("always");
    });

如上的一段代码,在服务端出错时(http状态码为:5XX、4XX),ajax绑定的done, fail, always方法竟然一个都没有被触发。挺意外的,为什么这样呢?难道是jQuery的bug?

仔细思考下jsonp的实现原理,其实不难找出问题的原因。

jsonp调用时其实是在header中创建一个script的dom节点,然后通过script的资源调用方式去向远程服务器发送请求的,问题的关键就在这个script标签上。如果想知道这个资源地址有没有请求成功,我首先想到的是onload和onerror这两个回调函数,遗憾的是,ie6,7,8都是不支持script的onload和onerror回调!我想,这个应该是jquery无法捕获到这个错误的原因吧。

那么有没有其它办法来处理这个错误呢,答案是有的,并且很简单,只要加上timeout参数即可:

    $.ajax({
        url: 'http://ptres.37.com/js/sq/modules/base44.js',
        type: 'GET',
        timeout: 2000,
        dataType: 'jsonp'
    })
    .done(function() {
        console.log("success");
    })
    .fail(function() {
        console.log("error");
    }).always(function(){
        console.log("always");
    });