跨域

来源:互联网 发布:南京网络作家协会 编辑:程序博客网 时间:2024/06/13 22:05

什么是跨域?

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

什么是同源策略?

同源,是指域名、协议、端口均为相同。

主域名:由两个或两个以上的字母构成,中间由点号隔开,整个域名只有一个点号。(csdn.net)
子域名:是在主域名之下的域名,域名内容会有多个点号

  • http://www.nealyang.cn/index.html 调用 http://www.nealyang.cn/server.php 非跨域
  • http://www.nealyang.cn/index.html 调用 http://www.neal.cn/server.php 跨域,主域不同
  • http://abc.nealyang.cn/index.html 调用 http://def.neal.cn/server.php 跨域,子域名不同
  • http://www.nealyang.cn:8080/index.html 调用 http://www.nealyang.cn/server.php 跨域,端口不同
  • https://www.nealyang.cn/index.html 调用 http://www.nealyang.cn/server.php 跨域,协议不同
  • localhost 调用 127.0.0.1 跨域

同源策略限制的行为?

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 和 JS 对象无法获取
  • Ajax请求发送不出去

跨域的解决办法?

1、JSONP跨域

什么是JSONP?

JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过JavaScript callback的形式实现跨域访问。

JSONP有什么作用?

由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。

如何使用JSONP?

jsonp跨域其实也是JavaScript设计模式中的一种代理模式。在html页面中通过相应的标签从不同域名下加载静态资源文件是被浏览器允许的,所以我们可以通过这个“犯罪漏洞”来进行跨域。一般,我们可以动态的创建script标签,再去请求一个带参网址来实现跨域通信

//原生的实现方式let script = document.createElement('script');script.src = 'http://www.nealyang.cn/login?username=Nealyang&callback=callback';document.body.appendChild(script);function callback(res) {  console.log(res);}
$.ajax({    url:'http://www.nealyang.cn/login',    type:'GET',    dataType:'jsonp',//请求方式为jsonp    jsonpCallback:'callback',    data:{        "username":"Nealyang"    }})

2、document.domain + iframe 跨域

这种跨域的方式最主要的是要求主域名相同。

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>html</title>    <script type="text/javascript" src = "jquery-1.12.1.js"></script></head><body>    <div>A页面</div>    <iframe     style = "display : none"     name = "iframe1"     id = "iframe"     src="http://b.nealyang.cn/1.html" frameborder="0"></iframe>    <script type="text/javascript">        $(function(){            try{                document.domain = "nealyang.cn"            }catch(e){}            $("#iframe").load(function(){                var jq = document.getElementById('iframe').contentWindow.$                jq.get("http://nealyang.cn/test.json",function(data){                    console.log(data);                });            })        })    </script></body></html>
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>html</title>    <script type="text/javascript" src = "jquery-1.12.1.js"></script>    <script type="text/javascript">        $(function(){            try{                document.domain = "nealyang.com"            }catch(e){}        })    </script></head><body>    <div id = "div1">B页面</div></body></html>

4、window.name + iframe 跨域

<body>  <script type="text/javascript">     iframe = document.createElement('iframe');    iframe.style.display = 'none';    var state = 0;    iframe.onload = function() {      if(state === 1) {          var data = JSON.parse(iframe.contentWindow.name);          console.log(data);          iframe.contentWindow.document.write('');          iframe.contentWindow.close();        document.body.removeChild(iframe);      } else if(state === 0) {          state = 1;          iframe.contentWindow.location = 'http://localhost:81/cross-domain/proxy.html';      }    };    iframe.src = 'http://localhost:8080/data.php';    document.body.appendChild(iframe);  </script></body>

5、location.hash + iframe 跨域

<body>  <script type="text/javascript">    function getData(url, fn) {      var iframe = document.createElement('iframe');      iframe.style.display = 'none';      iframe.src = url;      iframe.onload = function() {        fn(iframe.contentWindow.location.hash.substring(1));        window.location.hash = '';        document.body.removeChild(iframe);      };      document.body.appendChild(iframe);    }    // get data from server    var url = 'http://localhost:8080/data.php';    getData(url, function(data) {      var jsondata = JSON.parse(data);      console.log(jsondata.name + ' ' + jsondata.age);    });  </script></body>

6、postMessage跨域

发送信息的postMessage方法是向外界窗口发送信息

otherWindow.postMessage(message,targetOrigin);

targetOrigin是限定消息接受范围,不限制就用星号 *

。。。。。