跨域的方式总结

满足下面其中一个条件即要跨域:

  • 协议不同
  • 域名不同
  • 端口不同

跨域的方式我总结了以下几种:

第一种:window.name<iframe>标签实现跨域

  1. <iframe>标签的src能跨域;
  2. window.name属性值在文档刷新后依旧存在

使用
window.name的值是字符串形式,最大可2M。 服务器端:

//第一种php的代码
echo '<script> window.name = "{\"name\":\"xiaobai\", \"age\":100}" </script>';

我没有采用php的,而是用node.js起了一个服务器,监听了90端口。 代码如下:

var http=require("http");
http.createServer(function(req,res){
   res.writeHead(200,{'Content-Type':'text/html'});
   res.end("<script>window.name='{\"name\":\"xiaobai\", \"age\":100}'</script>");
}).listen(90);

将要返回的数据转化为字符串,赋值给window.name(是在JavaScript代码中)
客户端的: 注意:如果index.html页面和和该页面里的iframe框架的src如果不同源,则也无法操作框架里的任何东西,也就取不到iframe框架的name值了。所以要将iframe再链接到与index.html同源的页面,才能获取它的window.name值。

<script>
    function cross(url, fn) {
        var iframe = document.createElement("iframe");
        iframe.style.display = "none";
        var flag = 0;
        if(iframe.addEventListener){
            iframe.addEventListener("load", loadfn)
        }else if(iframe.attachEvent){
             iframe.attachEvent("onload", loadfn)
        }else{
            iframe.onload= loadfn;
        }
        iframe.src = url;
        document.body.appendChild(iframe);
        function loadfn(){
            if (flag==0) {
                flag = 1;
                iframe.contentWindow.location.href = "about:blank";
            } else {
                fn(iframe.contentWindow.name);
                iframe.contentWindow.close();
                document.body.removeChild(iframe);
            }
        }
    }
    function fn(data) {
        if(typeof JSON == 'undefined'){
        //为了兼容IE6 IE7 IE8(Q) 不支持 JSON 对象。
            var script=document.createElement("script");
            script.src="json2.js";//json2.js文件可以在网上下载
            document.body.appendChild(script);
         }
            data = JSON.parse(data);
        console.log(data);
    }
    cross("http://127.0.0.1:90/", fn);
</script>

完成!

第二种:JSONP跨域

JSONP的最基本的原理是:动态添加一个<script>标签,而<script>标签的src属性是没有跨域的限制的。 网上摘录的:
简述原理与过程:首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析<script>标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。(动态执行回调函数)
使用:
服务端代码:

//第一种php的代码
$jsonp = $_GET["callback"];
$str = $jsonp .'({name: xiaobai, age: 100})';
echo $str;

这里我同样才用的是node.js的代码
代码如下:

var http=require("http");
var url = require("url");
http.createServer(function(req,res){
 var params = url.parse(req.url, true).query;
   res.writeHead(200,{'Content-Type':'text/html'});
   var obj={
       name:"xiaobai",
       age:100
   }
   res.end(params.callback+"('"+JSON.stringify(obj)+"')");
}).listen(90);

客户端代码:

<script>
    if(typeof JSON == 'undefined'){
        var script=document.createElement("script");
        script.src="json2.js";
        document.body.appendChild(script);
    }
    function cross(url, fn) {
        var url=url+"?callback=fn";
        var script=document.createElement("script");
        script.src=url;
        document.body.appendChild(script);
    }

    function fn(data) {
        data = JSON.parse(data);
        console.log(data);
    }
    cross("http://127.0.0.1:90", fn);
</script>

完成!

第三种:html5的postMessage()跨域

window.postMessage是一个安全的跨源通信的方法 otherWindow.postMessage(message, targetOrigin); otherWindow是窗口引用,message将要发送到其他 window的数据,targetOrigin通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。这个大家可以去查一下api.

  • message事件 调函数第一个参数接收 Event 对象,有三个常用属性:
  • data:消息
  • origin:消息来源地址
  • source:发送消息的窗口对象

使用:
服务端:


var http=require("http");
http.createServer(function(req,res){
   res.writeHead(200,{'Content-Type':'text/html'});
   var obj={
       name:"xiaobai",
       age:100
   }

   obj=JSON.stringify(obj);
   res.end("<script>window.onmessage=function(e){ if(e.source!=window.parent) return; window.parent.postMessage('"+obj+"','*');}</script>");
}).listen(90)

客户端:

<script>
    if(typeof JSON == 'undefined'){
        var script=document.createElement("script");
        script.src="json2.js";
        document.body.appendChild(script);
    }
    function cross(url, fn) {
        var iframe=document.createElement("iframe");
        iframe.style.display="none";
        iframe.src=url;
        document.body.appendChild(iframe);
        iframe.onload= function () {
            iframe.contentWindow.postMessage('getData','http://127.0.0.1:90');
            window.onmessage=function(e){
                fn(e.data);
            }
        }

    }

    function fn(data) {
        data = JSON.parse(data);
        console.log(data);
    }
    cross("http://127.0.0.1:90", fn);
</script>

完成!

第四种:CORS(跨域资源共享)

CORS是XMLHttpRequest Level 2 里规定的一种跨域方式。在支持这个方式的浏览器里,javascript的写法和不跨域的ajax写法一模一样,只要服务器需要设置Access-Control-Allow-Origin: *因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
使用
服务端:

var http=require("http");
http.createServer(function(req,res){
   var options={
       'Content-Type':'text/html',
       'Access-Control-Allow-Origin':'http://localhost',//该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
    'Access-Control-Allow-Credentials':false,//该字段可选。它的值是一个布尔值,表示是否允许发送Cookie
    'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,OPTIONS',//各种请求方式
    'Access-Control-Allow-Headers':'X-Custom-Header'//该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段
   }
   res.writeHead(200,options);
   var obj={
       name:"xiaobai",
       age:100
   }
   obj=JSON.stringify(obj);
   res.end(obj);
}).listen(90)

客户端:

<script>
    if(typeof JSON == 'undefined'){
        var script=document.createElement("script");
        script.src="json2.js";
        document.body.appendChild(script);
    }
    function cross(url, fn) {
        var xhr = createCORSRequest('GET', url);
        xhr.onload = function() {
            var responseText = xhr.responseText;
            fn(responseText);
        };
        xhr.onerror = function() {
            console.log('There was an error!');
        };
        xhr.setRequestHeader('X-Custom-Header', 'value');//自定义头部字段
        xhr.send(null);
    }
    function createCORSRequest(method, url) {
        var xhr = new XMLHttpRequest();
        if ("withCredentials" in xhr) {
            //xhr.withCredentials = true;//不对cookies做任何事情,既不发送也不改变.服务端在处理这一请求时,也需要将Access-Control-Allow-Credentials设置为true
            // "withCredentials"属性是XMLHTTPRequest2中独有的
            xhr.open(method, url, true);

        } else if (typeof XDomainRequest != "undefined") {
            //IE
            // 检测是否XDomainRequest可用
            xhr = new XDomainRequest();
            xhr.open(method, url);
        } else {
            // CORS不被支持
            xhr = null;
        }
        return xhr;
    }
    function fn(data) {
        data = JSON.parse(data);
        console.log(data);
    }
    cross("http://127.0.0.1:90", fn);
</script>

完成!

转载于:https://www.cnblogs.com/bluey/p/6255312.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值