美文网首页
JSONP&跨域

JSONP&跨域

作者: D一梦三四年 | 来源:发表于2017-10-10 12:25 被阅读0次

1. 什么是同源策略

  • 同源指的是网页的协议、域名和端口都相同,不同源的客户端脚本在没明确授权的情况下,不能读写对方的资源。
  • 同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
  • 随着互联网的发展,现主要有三种行为受到同源策略的限制:
    • Cookie、LocalStorage 和 IndexDB 无法读取。
    • DOM 无法获得。
    • AJAX 请求不能发送。
URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二级域名(同上) 不允许
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名 不允许

2. 什么是跨域,跨域有几种实现形式?

  • 跨域:为了获取不同源网页上的图片、脚本等资源,我们就需要跨域了。
  • 跨域的方式
    • JSONP
    • CORS
    • WebSocket
    • postMessage
    • window.name
    • document.domain

3. JSONP 的原理是什么?

  • JSONP即 JSON with padding(填充式JSON或参数式JSON),是被包含在函数调用中的JSON,如callback({ "name": "xiaoming"})
  • JSONP是通过动态 <script> 元素来使用的,使用时可为 src 属性制定一个跨域URL,<script> 与 <img> 标签类似,都具有不受限制的从其它域加载资源的能力。因为JSONP是有效的 JavaScript 代码,在请求完成后,即JSONP响应加载到页面中以后,就会马上执行。
  • JSONP分两部分组成:回调函数和数据。回调函数是当响应到来时,应该在页面调用的函数,回调函数的名字一般是在请求中指定的;而数据就是传入回调函数中的JSON数据。如:http://www.a.com/?callback=handleResponse

4. CORS是什么?

  • CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS背后的基本思想,就是使用自定义的HTTTP头部让浏览器与服务器进行沟通,从而决定响应是成功还是失败。CORS需要浏览器和服务器同时支持,支持现代浏览器,IE支持10以上。
  • 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的 Ajax 通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该响应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 Ajax 请求没啥区别,代码完全一样。
  • 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

5. 跨域的解决方式

JSONP:利用<script>标签没有跨域限制来达到与第三方通讯的目的。

  1. 创建 index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Messages</title>
</head>
<body>
    <ul class="messages"></ul>

<script>
    var script = document.createElement('script');
    script.src = 'http://localhost:8080/getMessages?name=小明&callback=searchMessage';
    document.head.appendChild(script);
    document.head.removeChild(script);

    function searchMessage(person) {
        var html = '';
        for (var i = 0; i < person.length; i++) {
            html += '<li>' + person[i] + '</li>';
        }
        console.log(html);
        $('.messages').innerHTML = html;
    }

    function $(id) {
        return document.querySelector(id);
    }
</script>
</html>
  1. 创建 router.js
router.get('/getMessages', function (req, res) {
    var name = req.query.name;
    var messages = [];
    if (name === '小明') {
        messages.push("name: 小明", "age: 23")
    } else if (name === '小李') {
        messages.push("name: 小李", "age: 20")
    } else {
        return;
    }

    var cb = req.query.callback;
    if (cb) {
        res.send(cb + '(' + JSON.stringify(messages) + ')');
    } else {
        res.send(messages);
    }
})
  1. 打开本地服务器


    本地服务器.png
  2. 打开另外一个端口


    JSONP.png

CORS:在HTTP请求里添加特殊的头,允许服务器指定特定的域名可以跨域访问。

  1. 创建 index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Messages</title>
</head>
<body>
<button class="btn">获取信息</button>
<p class="messages"></p>
<script>
    var btn = document.querySelector('.btn');
    var messages = document.querySelector('.messages');
    btn.addEventListener('click', function () {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200 || xhr.status === 304) {
                    var results = JSON.parse(xhr.responseText);
                    messages.innerText += '姓名:' + results.name;
                }
            }
        }
        xhr.open('GET', 'http://localhost:8080/getMessages?name=小明', true);
        xhr.send();
    })
</script>
</html>
  1. 创建 router.js
router.get('/getMessages', function (req, res) {
    res.header('Access-Control-Allow-Origin', '*');
    var name = req.query.name;
    var data = {};
    if (name === '小明') {
        data = {name: "小明"}
    } else if (name === '小李') {
        data = {name: "小李"}
    } else {
        return;
    }
    res.send(data);
})
  1. 打开本地服务器


    本地服务器.png
  2. 打开另外一个端口
CORS.png

postMessage:允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

  1. 创建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>A</title>
</head>
<body>
<input id="inta" type="text" placeholder="aaa">
<p>我是A窗口</p>
<iframe src="http://192.168.0.248:8080/xxx.html" width="300px" height="200px" style="border: 1px dotted"></iframe>
<script type="text/javascript">
    var btna = document.getElementById('inta')
    btna.oninput = function(){
        window.frames[0].postMessage(this.value,'*')
    }
    window.addEventListener('message',function(e){
        btna.value.e.data
    })
</script>
</body>
</html>
  1. 创建 xxx.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>B</title>
</head>
<body>
<input id="intb" type="text" placeholder="bbb">
<p>我是B窗口</p>
<script type="text/javascript">
    var btnb = document.getElementById('intb')
    btnb.oninput = function(){
        window.parent.postMessage(this.value,'*')
    }
    window.addEventListener('message',function(e){
        btnb.value=e.data
    })
</script>
</body>
</html>
  1. 打开另外一个端口


    http-server.png
  2. 本地服务器


    postMessage.png

相关文章

  • JSONP&跨域

    1. 什么是同源策略 同源指的是网页的协议、域名和端口都相同,不同源的客户端脚本在没明确授权的情况下,不能读写对方...

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

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

  • 关于设置env等环境变量的思考

    1、如何处理跨域后台处理跨域前端处理跨域浏览器处理跨域 前端本地处理跨域:代理线上跨域的处理方式:Nginx反向代...

  • Web前后端跨域问题处理

    跨域问题有前台跨域(iframe间)和后台跨域。 前台跨域的解决方案可以采用跨域文档通讯(Cross domain...

  • 跨域

    跨域 什么是跨域: 解决跨域 通过jsonp原理:在页面引入跨域js和css时,没有存在跨域问题.因此可以动态创建...

  • 跨域问题详解分析

    参考文档 CORS详解 跨域资源共享 CORS 详解 js中几种实用的跨域方法原理详解 跨域的那些事儿 跨域与跨域...

  • 跨域问题:好几种解决方案

    跨域分为广义跨域和狭义跨域 广义跨域:一个域下的文档或脚本试图去请求另一个域下的资源; 广义跨域可以分为以下几种:...

  • ajax readystatus=0;status=0 报错

    跨域 跨域 跨域 一定要找运维或者后台解决

  • 深入跨域问题(2) - 利用 CORS 解决跨域

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

  • 响应头设置跨域和Spring注解跨域

    CORS跨域原理详解Spring解决跨域 响应头设置跨域 Spring注解跨域@CrossOrigin 可添加到方...

网友评论

      本文标题:JSONP&跨域

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