JSONP(url, {
data: {
key1: value1
},
callback: function (data) {
// data 是服务端返回的数据
}
})
实现可发送 JSONP 请求、获取 JSONP 返回结果的函数:
尝试封装了一个JSONP的函数。用来进行跨域操作。调用方式类似jQuery的ajax方式。
主要实现功能:
1.参数拼装。
2.给每个回调函数唯一命名。
3.在回调成功或请求失败之后删除创建的javascript标签。 需要兼容IE。IE下onerror事件不兼容。这里有对它的模拟实现。在IE下加载失败也能get到。
4.超时功能。超时取消回调。执行error。
5.error事件。可执行自己传入的error事件。
代码封装,调用,以及后台代码如下
jsonp.js
/*author:ls <841766635@qq.com>
* data:2016/03/20
*/
function JSONP(url,config){
var data = config.data || [];
var paraArr=[],paraString='';//get请求的参数。
var urlArr;
var callbackName;//每个回调函数一个名字。按时间戳。
var script,head;//要生成script标签。head标签。
var supportLoad;//是否支持 onload。是针对IE的兼容处理。
var onEvent;//onload或onreadystatechange事件。
var timeout = config.timeout || 0;//超时功能。
for(var i in data){
if(data.hasOwnProperty(i)){
paraArr.push(encodeURIComponent(i) + "=" +encodeURIComponent(data[i]));
}
}
urlArr = url.split("?");//链接中原有的参数。
if(urlArr.length>1){
paraArr.push(urlArr[1]);
}
callbackName = 'callback'+new Date().getTime();
paraArr.push('callback='+callbackName);
paraString = paraArr.join("&");
url = urlArr[0] + "?"+ paraString;
script = document.createElement("script");
script.loaded = false;//为了实现IE下的onerror做的处理。JSONP的回调函数总是在script的onload事件(IE为onreadystatechange)之前就被调用了。因此我们在正向回调执行之时,为script标签添加一个属性,然后待到onload发生时,再检测有没有这个属性就可以判定是否请求成功,没有成功当然就调用我们的error。
//将回调函数添加到全局。
window[callbackName] = function(arg){
var callback = config.callback;
callback(arg);
script.loaded = true;
}
head = document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild) //chrome下第二个参数不能为null
script.src = url;
supportLoad = "onload" in script;
onEvent = supportLoad ? "onload" : "onreadystatechange";
script[onEvent] = function(){
if(script.readyState && script.readyState !="loaded"){
return;
}
if(script.readyState == 'loaded' && script.loaded == false){
script.onerror();
return;
}
//删除节点。
(script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
script = script[onEvent] = script.onerror = window[callbackName] = null;
}
script.onerror = function(){
if(window[callbackName] == null){
console.log("请求超时,请重试!");
}
config.error && config.error();//如果有专门的error方法的话,就调用。
(script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));
script = script[onEvent] = script.onerror = window[callbackName] = null;
}
if(timeout!= 0){
setTimeout(function() {
if(script && script.loaded == false){
window[callbackName] = null;//超时,且未加载结束,注销函数
script.onerror();
}
}, timeout);
}
}
jsonp.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsonp测试</title>
<script src="jsonp.js"></script>
</head>
<body>
<script>
function myerror(){
alert('there must be something wrong!');
}
function getData (data){
alert("服务器过来的数据是"+data);
}
var url = 'http://runningls.com/demos/2016/jsonp/jsonp.php';
//调用函数。
JSONP(url,{
data:{
id:1
},
callback:getData,
error:myerror,
timeout:10000
});
</script>
</body>
<?php
$callback = $_GET['callback'];
$id = $_GET['id'];
if($id == 1){
$res = 'this is 1';
}
if($id == 2){
$res = 'this is 2';
}
$res = $callback."('$res')";
echo $res;
?>
演示地址: http://runningls.com/demos/2016/jsonp/jsonp.html
参考文章:http://www.cnblogs.com/rubylouvre/p/4277408.html
http://www.cnblogs.com/rubylouvre/archive/2011/02/13/1953087.html
转载请注明出处:http://blog.csdn.net/liusaint1992/article/details/50959571