2023.04.07 - 用jQuery发起JSONP请求失败后拿不到失败的回调

发布时间 2023-04-07 23:30:43作者: Yehuda

这是因为 JSONP 跨域请求是通过动态创建 script 标签来实现的,发送请求后,服务器会返回一段 JavaScript 代码,该代码会在当前页面中执行。由于 JavaScript 的同源策略的限制,我们不能直接从 JSONP 响应数据中获取 HTTP 状态码等信息。

在 JSONP 请求失败时,error 回调函数能够捕捉到的异常是一些与 HTTP 请求相关的异常,如请求超时、网络异常等。但是,如果 JSONP 请求未能成功连接到服务器或连接失败,是无法被 error 回调函数捕捉到的。因为这些异常并不是 HTTP 请求相关的异常,而是由于 JSONP 机制本身的限制而产生的。

如果需要获取关于连接失败的更多信息,可以在 script 标签的 onerror 回调函数里进行处理,该回调函数会在加载 script 标签过程中遇到异常时触发。

以下是一个示例代码:

var script = document.createElement('script');
script.src = 'http://example.com/api?callback=myCallback';
document.querySelector('head').appendChild(script);

script.onerror = function() {
  console.log('JSONP请求连接失败!');
};

在上面的代码中,通过创建一个 script 标签并将 src 属性设置为 JSONP 请求的 URL,插入到文档中,实现 JSONP 请求。通过 onerror 回调函数,可以捕捉到 JSONP 请求连接失败的异常,并执行相应的异常处理操作。需要注意的是,在使用该方法时,需要自定义回调函数名,在 URL 上添加 callback 参数。否则,在连接失败的情况下,无法区分是 JSONP 请求失败,还是返回数据格式不正确造成的异常。


当使用 jQuery 发送 JSONP 跨域请求时,可以通过 `timeout` 选项来设置请求超时时间。当请求超时时,`error` 回调函数会被触发,从而可以进行相应的异常处理。在设置了超时时间后,error 回调函数会处理两种类型的异常,即超时异常和请求返回的错误异常。为了分清是哪种异常,我们需要在 error 回调函数中进行判断。 可以根据 textStatus 参数来判断异常类型,如果其值为 'timeout',则是超时异常,否则则是请求返回的错误异常。

以下是一个使用 jQuery 实现的示例代码:

$.ajax({
  url: 'http://example.com/api',
  dataType: 'jsonp',
  timeout: 3000,
  success: function(data) {
    console.log(data);
  },
  error: function(jqXHR, textStatus, errorThrown) {
    if (textStatus === 'timeout') {
      console.log('请求超时!');
    } else {
      console.log('请求失败:', errorThrown);
    }
  }
});

在上面的代码中,使用 $.ajax 函数发送 JSONP 请求,并设置了 dataType 选项为 'jsonp'。同时,设置了 timeout 选项为 3000ms,即3秒。当请求超时时,error 回调函数会被触发,输出错误信息到控制台。如果请求成功,则 success 回调函数会被触发,处理返回的数据。

需要注意的是,在使用 jQuery 发送 JSONP 请求时,需要在 URL 上添加回调函数名称(如 callback=myCallback),让服务器将返回数据包装在回调函数中,并使用该名称作为参数传递。这样,jQuery 才能正确解析并处理返回的数据。

其他的异常,如网络连接失败等,是由 jQuery 底层的 XHR 对象抛出的,并可以通过 error 回调函数的参数获取。通过判断异常类型,可以进行相应的异常处理。


error 回调函数被触发时,会传递三个参数给它,分别代表请求状态、错误信息和(可选的)捕获的异常对象。这三个参数的具体含义如下:

  1. jqXHR(XMLHttpRequest 对象):即 AJAX 请求所创建的 XMLHttpRequest 对象,它包含了请求状态和错误信息等相关信息。可以通过调用 jqXHR.statusjqXHR.statusText 等属性来获取这些信息。
  2. textStatus(字符串):即请求的状态,它有四种可能的取值:'timeout'、'error'、'abort' 或 'parsererror',分别对应着请求超时、请求错误、请求中止和解析错误。可以根据状态值的不同,对请求异常进行不同的处理。
  3. errorThrown(字符串):即捕获的 JavaScript 异常对象,在异常发生时会被传递给 error 回调函数,一般包含了异常的具体信息。需要注意的是,在 JSONP 跨域请求时,异常信息通常比较有限,因为 JSONP 请求的返回值被包含在回调函数中,而不是直接作为响应数据返回。

error 回调函数中,根据这三个参数的值,可以进行相应的异常处理。例如,可以检查请求状态和返回的错误消息,输出相应的信息到控制台,提醒用户请求出现了异常。同时,可以利用捕获的 JavaScript 异常对象,对异常进行进一步的分析和处理。需要注意的是,出于安全考虑,在生产环境中不要将详细的异常信息直接输出给用户,而应该将其记录在服务器日志中,以便后续的排查和处理。