跨域访问简介及解决方法

1.同源策略

同源策略,是由网景(netscape)提出的一个著名的安全策略,现在所有的浏览器都会使用这一安全策略。所谓同源策略,即相互访问的页面之间必须具有相同的协议、端口和主机地址。

由于同源策略的限制,不同域名之间无法通过HTTP请求相互访问。我们把不同域名之间的访问问题称为跨域问题。

2.跨域访问

1.什么是跨域
跨域是指跨域名的访问,以下情况都属于跨域:

跨域原因说明 示例
域名不同 www.jd.com 与 www.taobao.com
域名相同,端口不同 www.jd.com:8080 与 www.jd.com:8081
二级域名不同 item.jd.com 与 miaosha.jd.com
协议不同 http://与https://

2.为什么有跨域问题?

跨域不一定会有跨域问题。

因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。

因此:跨域问题 是针对ajax的一种限制。

但是这却给我们的开发带来了不变,而且在实际生产环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同,怎么办?
3.解决跨域问题的方案
3.1静态

举例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://node.com/jsonp/jsonp.php"></script>
    <script>
        window.onload=function(){
            var btn=document.getElementById("btn");
            btn.addEventListener("click",function(){
                console.log(data)
            })
        }
    </script>
</head>
<body>
    <button id="btn">点击</button>
</body>
</html>
<?php
    echo "var data = {'username':'lisi'}";
?>

注意: php返回数据时,将变量名以字符串的方式返回,在js中会自动解析
3.2动态

举例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload=function(){
            var script=document.createElement("script");
            script.src="http://node.com/jsonp/jsonp.php";
            var head=document.getElementsByTagName("head")[0];
            head.appendChild(script);
            var btn=document.getElementById("btn");
            btn.addEventListener("click",function(){
                console.log(data)
            })
        }
    </script>
</head>
<body>
    <button id="btn">点击</button>
</body>
</html>
<?php
    echo "var data = {'username':'lisi'}";
?>

3.3jsonp

JSONP(JSON with Padding)可用于解决主流浏览器的跨域数据访问的问题)。跟JSON没有关系。

JSONP是如何实现跨域访问的?本质上是利用HTML元素的src属性都可以跨域的思路来解决的。

jsonp.php代码:

<?php
    $callback=$_GET["callback"];
    $name=$_GET["username"];
    $pwd=$_GET["pwd"];
    echo $callback.'('.'{"username":"'.$name.'","pwd":"'.$pwd.'"}'.')';
?>

客户端实现 callbackFunction 函数:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/javascript">
function callbackFunction(result, methodName)
{
    var html = '<ul>';
    for(var i = 0; i < result.length; i++)
    {
        html += '<li>' + result[i] + '</li>';
    }
    html += '</ul>';
    document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script type="text/javascript" src="https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>
</body>
</html>

在这里,我们对函数进行封装:

function json(obj){
    var defaults={
        type:"get",
        url:"",
        data:{},
        dataType:"jsonp",
        jsonp:"callback",
        success:function(data){
            console.log(data);
        }
    }
    for(var key in obj){
        defaults[key]=obj[key]
    };
    //回调函数名
    var cbName="jQuery"+("1.11.1"+Math.random()).replace(/\d/g,"")+"_"+(new Date().getTime());
    //判断是否传回调函数的名
    if(defaults.jsonpCallback){
        cbName=defaults.jsonpCallback;
    }
    window[cbName]=function(data){
        defaults.success(data);
    }
    //数据拼接
    var param="";
    for(var attr in defaults.data){
        param+="&"+attr+"="+defaults.data[attr];
    }
    
    //动态
    var script=document.createElement("script");
    script.src=defaults.url+"?"+defaults.jsonp+"="+cbName+param;
    var head=document.getElementsByTagName("head")[0];
    head.appendChild(script);
}

封装后,在html页面可以直接进行调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="json.js"></script>
    <script>
        $(function(){
            $("#btn").click(function(){
                json({
                    type:"get",
                    url:"http://node.com/jsonp/jsonp2.php",
                    data:{username:"admin",pwd:"123"},
                    dataType:"jsonp",
                    jsonp:"callback",
                    jsonpCallback:"callbackFunction",
                    success:function(data){
                        console.log(data)
                    }
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">点击</button>
</body>
</html>

拓展:jQuery 使用 JSONP
我们可以直接调用jquery中的getJSON()方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        $(function(){
            $("#btn").click(function(){
                $.getJSON("http://node.com/jsonp/jsonp.php?callBack=?",function(data){
                    console.log(data)
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">点击</button>
</body>
</html>

通过这个方法,我们也可以实现跨域功能

猜你喜欢

转载自blog.csdn.net/weixin_47150940/article/details/107789220