跨域请求之JSONP 三
script请求返回JSON实际上是脚本注入。它虽然解决了跨域问题,但它不是万能的。
- 不能接受HTTP状态码
- 不能使用POST提交(默认GET)
- 不能发送和接受HTTP头
- 不能设置同步调用(默认异步)
- ...
其最严重的就是不能提供错误处理,如果请求的代码正常执行那么会得到正确的结果。如果请求失败,如404,500之类,那么可能什么都不会发生。这篇在上一篇的基础上将着重解决JSONP的错误处理。
说可能是因为有些浏览器还是可以提供一些错误处理的。如IE9/10/Firefox/Safari/Chrome都支持script的onerror事件,如果请求失败,在onerror上可以进行必要的回调处理。但IE6/7/8/Opera却不支持onerror。这就是令人头疼的地方,打造一个完美的Sjax不太容易。
只要解决了IE6/7/8/Opera的onerror,整个就ok了。思路是逆向思维:请求成功则成功回调,否则就是失败回调。不拿onerror说事,因为它压根没onerror。因此只能那onload说事。就好比以下推论:
“你是对的” 推断出 “你没错”
因为我没办法知道你是“错的”。但我知道你是“对的”,只能拿是否对去推断你是否错了。
最后的实现细节如下:
1,IE9/Firefox/Safari/Chrome 成功回调使用onload事件,错误回调使用onerror事件
2,Opera 成功回调也使用onload事件(它压根不支持onreadystatechange),由于其不支持onerror,这里使用了延迟处理。即等待与成功回调success,success后标志位done置为true。failure则不会执行,否则执行。这里延迟的时间取值很有技巧,之前取2秒,在公司测试没问题。但回家用3G无线网络后发现即使所引用的js文件存在,但由于网速过慢,failure还是先执行了,后执行了success。所以这里取5秒是比较合理的。虽然这种方式间接实现了failure,但不彻底。
3,IE6/7/8成功回调使用onreadystatechange事件,错误回调几乎是很难实现的。令人恶心的是即使请求的资源文件不存在(404)。它的readyState也会经历“loaded”状态。这样你就没法区分请求成功或失败。最后使用前后台一起协调的机制解决最后的这个难题。无论请求成功或失败都让其调用callback(true)。 此时已经将区别成功与失败的逻辑放到了callback中,如果后台没有返回jsonp则调用failure,否则调用success。
接口:
|
1
2
3
4
5
6
7
|
Sjax.load(url, { data // 请求参数 (键值对字符串或js对象) success // 请求成功回调函数 failure // 请求失败回调函数 scope // 回调函数执行上下文 timestamp // 是否加时间戳}); |
示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>sjax_0.3.js by snandy</title></head><body><input type="button" value="Get Name" onclick="clk()"/><script type="text/javascript"> function clk(){ Sjax.load('jsonp66.js', { success : function(){alert(jsonp.name)}, failure : function(){alert('error');} }); }</script></body></html> |
以上html,点击“Get Name”按钮,调用clk函数。因为请求的资源jsonp66.js压根不存在。各浏览器下都会弹出“error”,当然Opera中会延迟一些。好了,本系列结束。
点击试试
相关:
http://stackoverflow.com/questions/3483919/script-onload-onerror-with-iefor-lazy-loading-problems
跨域请求之JSONP 三的更多相关文章
- JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)
1. 学习计划 第十一天: 1.sso注册功能实现 2.sso登录功能实现 3.通过token获得用户信息 4.Ajax跨域请求(jsonp) 2. Sso系统工程搭建 需要创建一个sso服务工程,可 ...
- 跨域请求之JSONP 一
跨域请求之JSONP 一 跨域请求的方式有很多种, iframe document.domain window.name script XDomainRequest (IE8+) XMLHTTPReq ...
- js跨域请求(jsonp)
jsonp是跨域请求的手段之一. jsonp的原理: 先来看看下面这段代码 <!DOCTYPE html> <html lang="en"> <hea ...
- 搞定所有的跨域请求问题 jsonp CORS
网上各种跨域教程,各种实践,各种问答,除了简单的 jsonp 以外,很多说 CORS 的都是行不通的,老是缺那么一两个关键的配置.本文只想解决问题,所有的代码经过亲自实践. 本文解决跨域中的 ge ...
- Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域
JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callba ...
- 跨域请求,jsonp
其实跨域请求,只需要在请求的url后面加上callback=?即可. 提供以下两种获取跨域的ajax的写法,都是基于jQuery.都已经成功使用,兼容做到ie7,(ie6未测试);案例地址来自豆瓣开放 ...
- Django跨域请求之JSONP和CORS
现在来新建一个Django项目server01,url配置为 url(r'^getData.html$',views.get_data) 其对应的视图函数为get_data: from django. ...
- Ajax+Spring MVC实现跨域请求(JSONP)(转)
背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...
- 跨域请求:JSONP
在JavaScript中,有一个很重要的安全性限制,被称为"同源策略".即JavaScript只能访问与包含它的文档在同一域下的内容.然而,当进行一些比较深入的前端编程的时候,不可 ...
随机推荐
- DBA_Oracle Erp R12中文补丁安装升级(案例)
2014-07-11 Created By BaoXinjian
- hdu1358 Period
首先给个博客:http://blog.csdn.net/lttree/article/details/20732385 感觉他说的很好,尤其是引用的那个博客,清晰的说明了循环节的两个公式. http: ...
- 白书 4.1.2 模运算的世界 P291
1.逆元 这里有个注意事项要说,就是当要求 (a-b)%m 的时候要注意不能直接 (a%m-b%m)%m 原因是得出的值有可能是负数,所以 (a%m-b%m+m)%m 才是正确的. //x,y是引用 ...
- Redirect 原理
mvc .net 中,从服务器端跳转页面有很多方法 有些不会改变浏览器地址栏的地址,这个好理解,mvc本身的机制就是action的名字不一定是view的名字 我们请求的不是文件名,在action中我们 ...
- reduce的数目到底和哪些因素有关
reduce的数目到底和哪些因素有关 1.我们知道map的数量和文件数.文件大小.块大小.以及split大小有关,而reduce的数量跟哪些因素有关呢? 设置mapred.tasktracker. ...
- c语言知识(1)
用freopen重定向输入 freopen函数以指定模式重新指定到另一个文件,模式用于指定新文件的访问方式. FILE *freopen(const char * restrict filename, ...
- ruby 字符串学习笔记1
1 从一种数据结构中构件字符串 hash = { key1: "val1", key2: "val2" } string = "" hash ...
- Lua 架构 The Lua Architecture
转载自:http://magicpanda.net/2010/10/lua%E6%9E%B6%E6%9E%84%E6%96%87%E6%A1%A3/ Lua架构文档(翻译) 十 102010 前段时间 ...
- 立体匹配:关于Middlebury提供的源码的简化使用
Middlebury提供的源码,虽然花了不到一个小时就运行起来啦.但说实话,它那循环读取脚本命令来执行算法真是让我费了不少头脑,花了近三天时间,我才弄明白了它的运行机制.你说,我就想提取一下算法,你给 ...
- android 资源文件
系统文档:http://developer.android.com/guide/topics/resources/available-resources.html 1. 系统下资源文件夹的名字是固定的 ...