zoukankan      html  css  js  c++  java
  • 跨域请求之JSONP 三

    script请求返回JSON实际上是脚本注入。它虽然解决了跨域问题,但它不是万能的。

    1. 不能接受HTTP状态码
    2. 不能使用POST提交(默认GET)
    3. 不能发送和接受HTTP头
    4. 不能设置同步调用(默认异步)
    5. ...

    其最严重的就是不能提供错误处理,如果请求的代码正常执行那么会得到正确的结果。如果请求失败,如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。

    接口:

    Sjax.load(url, {
    	data		// 请求参数 (键值对字符串或js对象)
    	success		// 请求成功回调函数
    	failure		// 请求失败回调函数
    	scope		// 回调函数执行上下文
    	timestamp	// 是否加时间戳
    });
    

    示例:

    <!DOCTYPE HTML>
    <html> 
    <head> 
    	<meta charset="utf-8"> 
    	<title>sjax_0.3.js by snandy</title>
    	<script src="https://files.cnblogs.com/snandy/sjax_0.3.js"></script>
    </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

    https://github.com/snandy/io

  • 相关阅读:
    《JavaScript DOM 编程艺术》读书笔记
    《精通CSS:高级Web标准解决方案》读书笔记
    计算机专业考研复试面试数据结构
    单元测试框架NUnit 之 Extensibility 例子
    单元测试框架NUnit 之 Extensibility可扩展性
    你应该知道的 asp.net webform之异步页面
    viewstate 应该注意的
    必须要知道的session
    javascript应该注意的小case数据类型
    单元测试框架NUnit 之 Attributes特性(二)
  • 原文地址:https://www.cnblogs.com/snandy/p/2034312.html
Copyright © 2011-2022 走看看