美文网首页
跨域(其中之四)

跨域(其中之四)

作者: 易景平 | 来源:发表于2018-12-16 09:44 被阅读0次

一. 通过JSONP跨域

利用script标签不受同源策略的影响的特性,在页面中动态插入script标签。script标签的src地址就是后端api接口地址,并以GET的方式将前端回调处理函数的名称告诉后端。后端收到这个请求以后,会将数据放在回调函数的参数位置返回。

由于<script>元素请求的脚本直接作为代码运行。这时,只要浏览器定义了这个回调函数,该函数就会立即调用。

index.html

<head>
    <meta charset="UTF-8">
    <title>JSON 跨域</title>
    <script type='text/javascript'>
    function addScriptTag(src) {
        var script = document.createElement('script');
        script.setAttribute("type","text/javascript");
        script.src = src;
        document.body.appendChild(script);
    }

    window.onload = function() {
        addScriptTag('http://localhost:8080?callback=foo')
    }

    function foo(data) {
        console.log(data.name+ '的淘气值是:' + data.naughty)
    }
    </script>
</head>
<body>
    
</body>

node.js

var http = require('http');
var url = require('url');
 var server = http.createServer(function(req, res) {
    var pathObj = url.parse(req.url, true);
    var data = {"name": "jack", "naughty": "49"};
    console.log(pathObj)
    var script = pathObj.search.split('=')[1] + '(' + JSON.stringify(data) + ')';
    res.write(script);
    res.end();
 }).listen(8080)
 console.log('visit http://localhost:8080')

二. postMessage

HTML5引入了一个全新的API:跨文档通信 API(Cross-document messaging),这个 API 为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。举例来说,父窗口aaa.com向子窗口bbb.com发消息,调用postMessage方法就可以了。

parent.html

<head>
    <meta charset="UTF-8">
    <title>parent</title>
    <script type="text/javascript"> 
    function sendIt() {
        //send message by postMessage
        var otherWindow = document.querySelector('#otherPage').contentWindow;
        var msg = document.querySelector('#message').value;
        otherWindow.postMessage(msg, 'http://bbb.com:8080')
    }
    </script>
</head>
<body>
    <iframe src="http://bbb.com:8080/child.html" frameborder="1" id="otherPage"></iframe>
    <br />
    <input type="text" id="message">
    <input type="button" value="send to child" onclick="sendIt()">
</body>

child.html

<head>
    <meta charset="UTF-8">
    <title>child</title>
    <script type="text/javascript">
    window.addEventListener('message', function(event){
        document.querySelector('#content').innerHTML += event.data
    }, false)
    </script>
</head>
<body>
    <p>Webpage from aaa.com</p>
    <div id="content"></div>
</body>

三. CORS

CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。。对于开发者来说,CORS 通信与普通的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨域,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感知。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。

CORS 请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
以下一简单请求为例:
浏览器发现这次跨域 AJAX 请求是简单请求,就自动在头信息之中,添加一个Origin字段。服务器回应的头信息Access-Control-Allow-Origin指定的Origin如果包含请求的Origin就可以完成跨域,否则会抛出错误。

index.html

<head>
    <meta charset="UTF-8">
    <title>CORS跨域</title>

</head>
<body>
    <div class="value"><p>这里显示结果</p></div>
    <button class="search">查询淘气值</button>

    <script type="text/javascript">
        function $(selector) {
            return document.querySelector(selector)
        }

        $('.search').addEventListener('click', function(){
            var xhr = new XMLHttpRequest()
            xhr.open('GET', 'http://localhost:8080/naughty', true)
            xhr.send()
            xhr.onload = function(){
                appendHTML(JSON.parse(xhr.responseText))
            }

        })
        function appendHTML(data){
            var html = '';
            html += '<p>' + data.name +'的淘气值是:' + data.naughty + '</p>';
            $('.value').innerHTML = html;
        }
    </script>
</body>

server.js

ar http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');

http.createServer(function(req, res) {
    var pathObj = url.parse(req.url, true);
    console.log(pathObj.pathname)
    switch (pathObj.pathname){
        case '/naughty':
        var data = {name: "jack", naughty: 49}
        res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080')
        res.end(JSON.stringify(data))
        break;
        default:
        fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
            if(e){
                res.writeHead(404,'not found')
                res.end('<h1>404 NOT FOUND</h1>')
            }else {
                res.end(data)
            }
        })
    }
}).listen(8080)
console.log('visit http://localhost:8080')

四. 降域

如果两个页面的origin有相似的部分,可以指定他们的document.domain为同一个origin。那么这两个不同源的页面就实现了跨域共享。

a.html

<head>
    <meta charset="UTF-8">
    <title>main page</title>
    <style>
        .ct {
            width: 910px;
            margin: auto;
        }
        .main {
            float: left;
            width: 450px;
            height: 300px;
            border: 1px solid #ddd;
        }
        .main input {
            margin: 20px;
            width: 200px;
        }
        iframe {
            float: right;
            width: 450px;
            height: 300px;
            border: 1px dashed #ddd;
        }
    </style>
</head>
<body>
    <div class="ct">
        <h1>使用降域实现跨域</h1>
        <div class="main">

            <input type="text" placeholder="http://a.jp.com:8080/a.html">
        </div>
        <iframe src="http://b.jp.com:8080/b.html" frameborder="0"></iframe>
        <script>
        document.querySelector('.main input').addEventListener('input', function(){
            console.log(this.value);
            window.frames[0].document.querySelector('input').value = this.value;
        })
        document.domain = "jp.com"
        </script>
    </div>
</body>

b.html

    <meta charset="UTF-8">
    <title>other page</title>
    <style>
        html, body {
            margin: 0;
        }
        input {
            margin: 20px;
            width: 200px;
        }
    </style>
</head>
<body>
    <input type="text" id="input" placeholder="http://b.jp.com:8080/b.html">
    <script>
        document.querySelector('#input').addEventListener('input', function(){
            window.parent.document.querySelector('input').value = this.value;
        })

        document.domain = "jp.com";
    </script>
</body>
降域.jpg

相关文章

  • 跨域(其中之四)

    一. 通过JSONP跨域 利用script标签不受同源策略的影响的特性,在页面中动态插入script标签。scri...

  • 跨域请求(CORS)要点

    前端开发的童鞋,应该都有听过跨域请求,但这其中的细节可能还不清楚,比如: 什么是跨域请求? 为什么会存在跨域请求?...

  • VUE-PC端项目遇到的坑总结

    1.跨域 其中说到跨域的话首要的就是axios的配置 // 创建axios实例axios.defaults.tim...

  • 一个小例子学习JSONP的基本使用

    在JavaScript中Ajax是无法跨域的,当协议或者域名或者端口任一不同时,都会出现跨域,跨域处理的其中一种方...

  • 学习记录000之跨域&&Token&&a

    学习记录000之跨域&&Token&&Restful设计 1.跨域 1.1什么是跨域 一张图来了解下哪些情况下存在...

  • Ajax跨域问题

    一、跨域问题 二、跨域的定义以及产生原因 三、解决思路 四、JSONP 五、跨域解决的方向 五、浏览器禁止检查

  • jsonp跨域

    什么是跨域 请求协议(http,https)不同 域名(domain)不同 端口(port)不同 跨域解决方案之 ...

  • nginx配置允许跨域

    nginx设置允许跨域 这一段可以放在http、server、location里面分别代表不同程度的跨域,其中Ac...

  • 深入跨域问题(3) - 利用 JSONP 解决跨域

    深入跨域问题(1) - 初识 CORS 跨域资源共享;深入跨域问题(2) - 利用 CORS 解决跨域深入跨域问题...

  • 4种方法解决js跨域的实现方式

    一、JSONP 使用ajax实现跨域: 二、CORS跨域资源共享 三、Nginx反向代理 四、webpack (在...

网友评论

      本文标题:跨域(其中之四)

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