欢迎来到 jackNEss'窝窝
I like simple mind

JSONP实现跨域数据传输

2012年07月23日

JSONP实现跨域数据传输

最近的项目中用到了跨域异步传输,第一时间就想到了JSONP,可惜上网一搜,几乎都是用jQuery提供的方法or其他库提供的现成方法实现,原生JS的反而没有(起码我是没发现),经过研究和整理,给大家分享一下使用原生JS实现 读取 JSONP。

何为JSONP?

JSONP(JSON with Padding) 是資料格式 JSON 的一種“使用模式”,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com 的伺服器溝通,而 HTML 的 <script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的 JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。

JSONP工作原理

首先,我们要声明一个用于获取json数据格式的函数:

/* js document */
//用于装载json数据的变量
var jsonData;

//用于将 获取到的json数据 赋值到 jsonData中
var jsonCallback = function(data){
	jsonData = data;
}

然后,我们会通过动态插入 <script> 标签 并将其url地址指向输出json格式的页面地址:

<!-- html document -->
<script type="text/javascript" src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="a.php?flvid=MTE1MjE2MDc0&callback=jsonCallback"></script>

值得注意的是,我们传过去的数据必须把我们需要执行获取json数据的函数名传过去,在这个例子中,即 jsonCallback,

而在我们生产json格式的文件 a.php中,输出的格式如下:

jsonCallback({"name":"jackNEss","date":"2012-7-23"})

而php代码类似于这样(php不会,不知道有木有写错 ^_^# 大家意会吧,意会!):

<?php echo $_GET["callback"]; ?>({"name":"jackNEss","date":"2012-7-23"})

由于一旦生产就会马上执行 jsonCallback() 方法,所以不必判断这个a.php是否加载完,我们要做的,只需要确保我们这个 jsonCallback 方法在这个 a.php执行之前已经声明好,这样就能确保不出错。

到最后,我们要记得把插入的 <script> 标签 移除掉。

我封装好的方法

下面是我封装好的一个获取 jsonp的方法:

var jns = {};
/*
 * jsonp 异步传输
 * jns.getJSONP(op)
 * op.url:              action地址
 * op.querystring:      参数
 * op.success:          成功时callback
 * op.error:            失败时callback
 * 可不填写变量 ------------------------
 * op.callbackName:     callback 返回的函数名,支持自动生成
 * op.callbackQueryAttr:callback attr 调用 callback的 querystring变量
 * exp:
	完整
	jns.getJSONP({
		url:"a.php",
		quertstring:"flvid=MTE1MjE2MDc0",
		success:function(data){alert(data)},
		error:function(){alert("loaded error")},
		callbackQueryAttr:"callback",
		callbackName:"jnsJsonpData"
	})
	jns.getJSONP({url:"a.php",querystring:"flvid=MTE1MjE2MDc0",success:function(data){alert(data)}})
 * date:2012-7-29
 * ver 2.0
 */
jns.getJSONP = function(op){
	var _this = arguments.callee;
	if(!_this.count){
		_this.count = 0;
	}

	var option = {
		//action地址
		url:"",
		//参数
		querystring:"",

		//callback 函数名,支持自动生成
		callbackName:"jnsJsonpData" + (++_this.count),

		//callback attr 调用 callback的 querystring变量 例如 callback = a,后端部分则是 a({...})
		callbackQueryAttr:"callback",

		//成功时callback
		success:function(){},

		//失败时callback
		error:function(){}
	}

		
	if(!op){op = {};}
	typeof op.url == "string"? option.url = op.url:"";
	typeof op.querystring == "string"? option.querystring = op.querystring:"";
	typeof op.callbackName == "string"? option.callbackName = op.callbackName:"";
	typeof op.callbackQueryAttr == "string"? option.callbackQueryAttr = op.callbackQueryAttr:"";
	typeof op.success == "function"? option.success = op.success:"";
	typeof op.error == "function"? option.error = op.error:"";

   

	
	var dc = document,
		url = option.url + (option.url.split("?").length > 1?"&":"?") + option.querystring + "&" + option.callbackQueryAttr + "=" + option.callbackName,
		callback = option.success,
		script,
		dFragment = dc.createDocumentFragment();
	
	script = dc.createElement("script");
	script.type = "text/javascript";
	window[option.callbackName] = function(data){
		try{
			option.success(data);
		}
		catch(err){
			option.error();
		}
		finally{
			dFragment.appendChild(script);
			//script.parentNode.remove(script); 使用这种方式移除script在某些情况下会令到ie6崩溃,故在这里不建议使用
			window[option.callbackName] = null;
			
		}

	}
	script.src = url;
	dc.getElementsByTagName("head")[0].appendChild(script);
};

这里是 demo 地址:http://www.jackness.org/lab/2012/jsonp/demo.html

分类javascript
标签
阅读 784
  • 评论加载中...

标签云

分类目录

最新留言

  • 评论加载中...

与我联系

如有疑问or建议可通过以下方式跟我取得联系.

Q Q:373435871
Email:jackness1208@gmail.com
© Copyright 2011 - 2014 jackNEss.org All Rights Reserved 粤ICP备14065612号
首页 | 关于我 | 网站地图 | RSS