跨域

作者: 白柏更好 | 来源:发表于2017-10-18 18:28 被阅读0次

    同源策略

    同源策略是对XHR的一个主要约束,它为通信设置了“相同的域”,“相同的端口”,“相同的协议”一系列限制,浏览器从安全角度出发,只允许在本域下的接口交互,不同源的客户端在没有明确授权的情况下,不能读写限制之外的资源,除非采用被认可的跨域方案。而跨域资源嵌入是被允许的,页面中的连接,重定向和表单提交也是被允许的。

    跨域方式

    • JSONP
    • CORS(Cross-Origin Resource Sharing,跨域资源共享)
    • 降域
    • postMessage

    JSONP的原理

    JSONP(JSON with padding)填充式JSON,JSONP主要由回调函数和数据(传入回调函数的JSON数据)组成,因为浏览器允许跨域资源嵌入,所以JSONP是通过在页面内动态地添加<script>,为标签内src添加一个跨域URL,其中包含在之前声明好的回调函数(?callback=回调函数名),当JSONP响应加载完毕以后,则会立即执行。

    • 缺点:
      1. 不能确保从其它域中加载的代码中是否含有恶意代码。
      2. 确定JSONP请求是否失败并不容易(HTML5中为script元素添加的oneerror事件处理程序并没有得到任何浏览器支持)
    <script>
        document.querySelector(".change").addEventListener('click',function(){
            var newScript = document.createElement("script");
            newScript.src = "http://localhost:8080/getItems?callback=appendHtml";
            document.head.appendChild(newScript);
            document.head.removeChild(newScript);
        });
    
    //声明回调函数
        function appendHtml(items){
            var html = '';
            for(var i=0;i < items.length;i++){
                html +='<li>' + items[i] + '</li>';
            }
            console.log(html);
            var add = document.querySelector('.ct');
            add.innerHTML = html;
        }
    </script>
    
     var backMs = req.query.callback;
        if(backMs){
            res.send(backMs + '(' +JSON.stringify(data) + ')' );
        } else {
            res.send(data);
        }
    

    CORS

    CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。

    <script>
        var btn = document.querySelector(".change")
        var ct = document.querySelector(".ctn")
        btn.addEventListener("click",function(){
            var xhr = new XMLHttpRequest()
            xhr.open('get', 'http://haoren.com:8080/getJobs',true)
            xhr.send()
            xhr.onreadystatechange = function(){
                if ( xhr.readyState === 4 && xhr.status === 200){
                    console.log(xhr.responseText)
                    render(JSON.parse(xhr.responseText))
                }
            }
    
    
        })
        function render(newLi){
            var html = ''
            for(var i = 0; i < newLi.length; i++){
                html += '<li>' + newLi[i] + '</li>'
            }
            ct.innerHTML = html
        }
    </script>
    
    app.get("/getItems",function(req,res){
        var jobs = [
            "4444444",
            "5555555",
            "6666666",
            "7777777",
            "8888888",
            "9999999"
        ]
        var data = []
        for(var i = 0; i < 3; i++){
            var index = parseInt(Math.random() * jobs.length)
            data.push(jobs[index])
        }
    res.header("Access-Control-Allow-Origin","http://huairen.com:8080")    //添加一个响应头
    res.send(data)
    

    PostMessage

    parent

    <div class="main">
            <input type="text" placeholder="http://huairen.com:8080">
        </div>
        <iframe src="http://haoren.com:8080/jiangyu2.html"></iframe>
        <script>
            document.querySelector('.main input').addEventListener('input',function(){
                window.frames[0].postMessage(this.value,'*');
            })
            window.addEventListener('message',function(e){
                document.querySelector('.main input').value = e.data
            });
        </script>
    

    child

    <body>
        <input type="text" id="input" placeholder="http://haoren.com:8080">
    </body>
    <script>
        document.querySelector('#input').addEventListener("input",function(){
            window.parent.postMessage(this.value,'*')
        })
        window.addEventListener('message',function(e){
            document.querySelector('#input').value = e.data
        })
    </script>
    

    降域

    a.html

    <script>
            document.querySelector('.main input').addEventListener('input', function() {
                console.log(this.value)
                window.frames[0].document.querySelector('input').value = this.value
            })
            document.domain = 'localhost'   //做降域处理
        </script>
    

    b.html

    <script>
            document.querySelector('input').addEventListener('input', function() {
                console.log(this.value)
                window.parent.document.querySelector('input').value = this.value
            })
            document.domain = 'localhost'   //做降域处理
        </script>
    

    相关文章

      网友评论

          本文标题:跨域

          本文链接:https://www.haomeiwen.com/subject/dovqyxtx.html