1.jsonp方法

转:https://blog.csdn.net/liusaint1992/article/details/50959571

主要实现功能:

1.参数拼装。

2.给每个回调函数唯一命名。

3.在回调成功或请求失败之后删除创建的javascript标签。 需要兼容IE。IE下onerror事件不兼容。这里有对它的模拟实现。在IE下加载失败也能get到。

4.超时功能。超时取消回调。执行error。

5.error事件。可执行自己传入的error事件。

代码封装,调用,以及后台代码如下

/*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;  
  
?>

  2.hash方法

//利用hash,场景是当前页面A 通过iframe 和frame嵌入跨域的页面B
//在A中伪代码如下:
var B = document。个体ElementsByTagName('iframe');
B.src = B.src + '#' + 'data';
//在B 中的伪代码如下
window.onhashchange = function(){
var data = window.location.hash;
}

  3.postMessage

 

//窗口A(http:A.com)向跨域的窗口B(http://B.com)发送信息
window.postMessage('data','http://B.com');//B窗口 //在窗口B中监听; window.addEventListener('message',function(event){ console.log(event.origin); //http://A.com console.log(event.source);//Bwindow console.log(event.data); //data },false);

  4.webSocket方法

//websocket 【 参考质料】(http://www.ruanyifeng.com/blog/2017/05/websocket.html)
var ws = new WebSocket('wss://echo.websocket.org');
ws.onpen = function(evt){
    console.log.('Connection open ...');
    ws.send('hello websockets')
}
ws.onmessage = function(evt){
  console.log('Received message:'+evt.data)  
  ws.close()  
}
ws.onclose = function (evt){
  console.log('connection closed.')  
}

  5.CORS方法

//CORS【 参考质料】(http://www.ruanyifeng.com/blog/2016/04/cors.html)
//url (必须),options(可选) 
fetch('/some/url',{
//配置属性才能跨域
method:'get
}).then(function(response){

}).catch(function(err){
//出错了,等价于 then 的第二个参数
});

  

posted on 2018-05-06 21:12  前端入门菜鸟  阅读(193)  评论(0编辑  收藏  举报