jquery ajax 使用 jsonp 时,请求被拒绝/超时后不执行error或者fail方法问题的解决方案

您所在的位置:网站首页 pkgj108无法获取列表发送请求失败 jquery ajax 使用 jsonp 时,请求被拒绝/超时后不执行error或者fail方法问题的解决方案

jquery ajax 使用 jsonp 时,请求被拒绝/超时后不执行error或者fail方法问题的解决方案

2024-07-18 01:06:57| 来源: 网络整理| 查看: 265

解决方案: 代码如下:

$.ajax( dataType: "jsonp", type: "get", url: "http://127.0.0.1:8989/api/ReadMsg", success: function (data) {}, error: function (err) {}; );

会在head第一个位置生成一个script标签, 如下

使用此方案解决: 请求被拒绝/net::ERR_CONNECTION_REFUSED/超时/net::ERR_CONNECTION_TIMEOUT

var script = $("script[src^='http://127.0.0.1:8989/api/ReadMsg?ie=1']")[0]; script.onerror = function(evt) { alert('网络异常'); };

**

以下为转载原文: https://www.jb51.net/article/75768.htm

**

什么是域,简单来说就是协议+域名或地址+端口,3者只要有任何一个不同就表示不在同一个域。跨域,就是在一个域中访问另一个域的数据。 如果只是加载另一个域的内容,而不需要访问其中的数据的话,跨域是很简单的,比如使用iframe。但如果需要从另一个域加载并使用这些数据的话,就会比较麻烦。为了安全性,浏览器对这种情况有着严格的限制,需要在客户端和服务端同时做一些设置才能实现跨域请求。 JSONP简介 JSONP(JSON with Padding)是一种常用的跨域手段,但只支持JS脚本和JSON格式的数据。顾名思义,JSONP是利用JSON作为垫片,从而实现跨域请求的一种技术手段。其基本原理是利用HTML的

// 设置crossDomain和dataType参数以使用JSONP $.ajax({ dataType: "jsonp", url: "http://www.example.com/xxx", crossDomain: true, data: { } }).done(function() { // 请求完成时的处理函数 }); // 使用getJSON $.getJSON("http://www.example.com/xxx?jsoncallback=?", { // 参数 }, function() { // 请求完成时的处理函数 });

使用getJSON时,需要在参数中指定jsoncallback=?,这个就是前面所说的回调函数,JQuery会自动以一个随机生成的值(回调函数名)来替换该参数中的问号部分,从而形成jsoncallback=jQueryxxxxxxx这种形式的参数,然后和其他参数一起使用GET方式发出请求。 使用第一种方式时,只要将dataType参数的值指定为jsonp,JQuery就会自动在请求地址后面加上jsoncallback参数,因此无需手动添加。 JQuery跨域请求的缺陷:错误处理 跨域请求可能会失败,比如对方服务器的安全设置拒绝接受来自我方的请求(我方不在对方的信任列表中),或者网络不通,或对方服务器已关闭,或者请求地址或参数不正确导致服务器报错等等。 在JQuery中,当使用ajax或getJSON发送请求后会返回一个jqXHR对象[3]。该对象实现了Promise协议,所以我们可以使用它的done、fail、always等接口来处理回调。例如我们可以用在它的fail回调中进行请求失败时的错误处理:

var xhr = $.getJSON(...); xhr.fail(function(jqXHR, textStatus, ex) { alert('request failed, cause: ' + ex.message); });

这种方式能够处理“正常的错误”,例如超时、请求被中止、JSON解析出错等等。但它对那些“非正常的错误”,例如网络不通、服务器已关闭等情况的支持并不好。 例如当对方服务器无法正常访问时,在Chrome下你会在控制台看到一条错误信息: 在这里插入图片描述 JQuery不会处理该错误,而是选择“静静地失败”:fail回调不会执行,你的代码也不会得到任何反馈,所以你没有处理这种错误的机会,也无法向用户报告错误。 一个例外是在IE8。在IE8中,当网络无法访问时,< script>标签一样会返回加载成功的信息,所以JQuery无法根据< script>标签的状态来判断是否已成功加载,但它发现< script>标签“加载成功”后回调函数却没有执行,所以JQuery以此判断这是一个“解析错误”(回调代码没有执行,很可能是返回的数据不对导致没有执行或执行失败),因此返回的错误信息将是“xxxx was not called”,其中的xxxx为回调函数的名称。 也就是说,由于IE8(IE7也一样)的这种奇葩特性,导致在发生网络不通等“非正常错误”时,JQuery反而无法选择“静默失败”策略,于是我们可以由此受益,得到了处理错误的机会。例如在这种情况下,上面的例子将会弹出“xxxx was not called”的对话框。 解决方案 当遇到“非正常错误”时,除了IE7、8以外,JQuery的JSONP在较新的浏览器中全部会“静默失败”。但很多时候我们希望能够捕获和处理这种错误。 实际上在这些浏览器中,< script>标签在遇到这些错误时会触发error事件。例如如果是我们自己来实现JSONP的话可以这样:

var ele = document.createElement('script'); ele.type = "text/javascript"; ele.src = '...'; ele.onerror = function() { alert('error'); }; ele.onload = function() { alert('load'); }; document.body.appendChild(ele);

在新浏览器中,当发生错误时将会触发error事件,从而执行onerror回调弹出alert对话框: 在这里插入图片描述 但是麻烦在于,JQuery不会把这个< script>标签暴露给我们,所以我们没有机会为其添加onerror事件处理器。 下面是JQuery实现JSONP的主要代码:

jQuery.ajaxTransport( "script", function(s) { if ( s.crossDomain ) { var script, head = document.head || jQuery("head")[0] || document.documentElement; return { send: function( _, callback ) { script = document.createElement("script"); script.async = true; ... script.src = s.url; script.onload = script.onreadystatechange = ...; head.insertBefore( script, head.firstChild ); }, abort: function() { ... } }; } });

可以看到script是一个局部变量,从外部无法获取到。 那有没有解决办法呢?当然有:

自己实现JSONP,不使用JQuery提供的修改JQuery源码(前提是你不是使用的CDN方式引用的JQuery)使用本文介绍的技巧

前两种不说了,如果愿意大可以选择。下面介绍另一种技巧。 通过以上源码可以发现,JQuery虽然没有暴露出script变量,但是它却“暴露”出了< script>标签的位置。通过send方法的最后一句: head.insertBefore( script, head.firstChild ); 可以知道这个动态创建的新创建标签被添加为head的第一个元素。而我们反其道而行之,只要能获得这个head元素,不就可以获得这个script了吗?head是什么呢?继续看源码,看head是怎么来的: head = document.head || jQuery(“head”)[0] || document.documentElement; 原来如此,我们也用同样的方法获取就可以了,所以补全前面的那个例子,如下:

var xhr = $.getJSON(...); // for "normal error" and ie 7, 8 xhr.fail(function(jqXHR, textStatus, ex) { alert('request failed, cause: ' + ex.message); }); // for 'abnormal error' in other browsers var head = document.head || $('head')[0] || document.documentElement; // code from jquery var script = $(head).find('script')[0]; script.onerror(function(evt) { alert('error'); });

这样我们就可以在所有浏览器(严格来说是绝大部分,因为我没有测试全部浏览器)里捕获到“非正常错误”了。 这样捕获错误还有一个好处:在IE7、8之外的其他浏览器中,当发生网络不通等问题时,JQuery除了会静默失败,它还会留下一堆垃圾不去清理,即新创建的< script>标签和全局回调函数。虽然留在那也没什么大的危害,但如果能够顺手将其清理掉不是更好吗?所以我们可以这样实现onerror:

// handle error alert('error'); // do some clean // delete script node if (script.parentNode) { script.parentNode.removeChild(script); } // delete jsonCallback global function var src = script.src || ''; var idx = src.indexOf('jsoncallback='); if (idx != -1) { var idx2 = src.indexOf('&'); if (idx2 == -1) { idx2 = src.length; } var jsonCallback = src.substring(idx + 13, idx2); delete window[jsonCallback]; }

这样一来就趋于完美了。

function jsonp(url, data, callback) { var xhr = $.getJSON(url + '?jsoncallback=?', data, callback); // request failed xhr.fail(function(jqXHR, textStatus, ex) { /* * in ie 8, if service is down (or network occurs an error), the arguments will be: * * testStatus: 'parsererror' * ex.description: 'xxxx was not called' (xxxx is the name of jsoncallback function) * ex.message: (same as ex.description) * ex.name: 'Error' */ alert('failed'); }); // ie 8+, chrome and some other browsers var head = document.head || $('head')[0] || document.documentElement; // code from jquery var script = $(head).find('script')[0]; script.onerror = function(evt) { alert('error'); // do some clean // delete script node if (script.parentNode) { script.parentNode.removeChild(script); } // delete jsonCallback global function var src = script.src || ''; var idx = src.indexOf('jsoncallback='); if (idx != -1) { var idx2 = src.indexOf('&'); if (idx2 == -1) { idx2 = src.length; } var jsonCallback = src.substring(idx + 13, idx2); delete window[jsonCallback]; } }; }

上代码在IE8、IE11、Chrome、FireFox、Opera、360下测试通过,其中360是IE内核版本,其他浏览器暂时未测。 希望本文对大家学习,帮助大家解决jQuery使用JSONP时产生的错误。

**

以上为转载原文: https://www.jb51.net/article/75768.htm

**



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭