• 跨域的方式总结


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

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

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

    第一种: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>
    

    完成!

  • 相关阅读:
    woj 1574
    UESTC 594 我要长高 dp单调队列
    HDU 3401 Trade dp 单调队列优化
    HDU 2844 Coins 多重背包
    2-1
    1-2
    1-1
    12-1
    9-1
    14-8
  • 原文地址:https://www.cnblogs.com/bluey/p/6255312.html
Copyright © 2020-2023  润新知