用iframe 拉取json数据的通用做法

根据对iframe和script的理解,写了个iframe拉取数据的demo

	function suc(o) { console.log(o); }
	function error () { console.log('on error'); }
	function getdata(uri, cbname, succ, error) {
		var doc=document;
		cbname = cbname || 'callback';
		// 判断域名,如果页面写了domain,子页面也要设置domain,才能获得相应的对象
		var _dm = (document.domain == location.host)?'':'document.domain="' + document.domain + '";';
		var html = '<!DOCTYPE HTML><html><head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title></title></head><body><script>' + _dm + cbname + '=frameElement.bc; frameElement.get(document);<\/script> </body> </html>';


		var ifr = doc.createElement('iframe');
		doc.body.appendChild(ifr);

		ifr['get'] = function(doc) {
			var sender = doc.createElement("script");
			sender.onreadystatechange = function() {
				if (sender && sender.readyState == "loaded") try {
					ifr.ecb();
				} catch(ignore) {}
			};
			sender.src = uri;
			doc.body.appendChild(sender);
		};

		ifr['bc'] = function() {
			succ.apply(null, arguments);
			// 正常逻辑处理完,把异常错误处理函数清理掉,就不会被调用了
			ifr.ecb = null;
		};
		ifr['ecb'] = function() {
			error();
		};

		// 发起请求
		ifr.src= 'javascript:void((function(){var doc=document;doc.open(\'text/html\', \'replace\'); doc.write(\''+html+'\');doc.close()})())';
	}

	var url = '/test.php';
	getdata(url, '_bc' ,  suc, error);

来看这句:
ifr.src= ‘javascript:void((function(){var doc=document;doc.open(\’text/html\’, \’replace\’); doc.write(\”+html+’\');doc.close()})())’;

本来想的做法是直接获取iframe的docuement, 但是当当前页面设置了domain 的时候,这个iframe的document在ie下就获取不到了(别的浏览器可以的), 被禁止访问了。 上面的这个做法的好处是即使设置了domain, 也是可以获取document对象的, 不过记得在子页面也要设置一下domain, 不然父子页面间也是无法访问的。

代码中的:
<script>’ + _dm

可以获得iframe 的document 对象了, 就可以用script 拉取数据了
doc.open(\’text/html\’, \’replace\’); doc.write(\”+html+’\');doc.close();
用这句话在创建的空iframe里注入我们的拉取脚本

如何获取数据的:
iframe 中: frameElement.get(document);
父页面 : ifr['get'] = function(doc)
这两句应该很明白了,在父页面中执行脚本, 但是用子页面的document对象。

然后就是用script去获取数据了
var sender = doc.createElement(“script”);
sender.onreadystatechange = function() {

};
sender.src = uri;
doc.body.appendChild(sender);

有一点值得一提是脚本的错误处理了ecb了。

另一篇拉取数据的可参考:
http://www.sdvil.com/js/459
关于script可参考:
http://www.sdvil.com/js/378

Leave a Comment