前端面试-跨域那些事儿

了解跨域以前,咱们先来了解以下两个知识点javascript

  1. URL组成css

    URL:协议 + 域名 + 端口号(默认为8080可省略) + 参数html

  2. 浏览器同源策略前端

    所谓同源是指,域名,协议,端口相同。java

    同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,所以拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,可是没法被浏览器接收。segmentfault

    不知足同源策略的条件的网页,是不可以互相通讯的,这时候就须要咱们使用跨域来解决这个问题后端

1.跨域方法概览

  • JSONP
  • PostMessage
  • domain
  • Hash
  • 跨域资源共享(CORS)
  • WebSocket协议跨域

2. JSONP 跨域

  • 经过在界面动态写入 script 标签,设置src属性,将请求以URL参数的形式附加在URL中,而且指定回调函数
  • 服务器返回回调函数,而且将数据看成回调函数的参数返回
  • 在界面定义回调函数,服务器返回以后会直接调用

代码示例:跨域

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);

    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>
复制代码

服务器返回以下,返回即执行浏览器

handleCallback(someData)
复制代码

3. postMessage详解

postMessage方法接收两个参数服务器

  • data
  • origin:发送目标的URL地址

代码示例:

  1. a.html:http://www.domain1.com/a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2传送跨域数据
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };

    // 接受domain2返回数据
    window.addEventListener('message', function(e) {
        alert('data from domain2 ---> ' + e.data);
    }, false);
</script>
复制代码
  1. b.html:http://www.domain2.com/b.html
<script>
    // 接收domain1的数据
    window.addEventListener('message', function(e) {
        alert('data from domain1 ---> ' + e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;

            // 处理后再发回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
        }
    }, false);
</script>
复制代码

4. domain

此方法仅限主域相同,子域不一样的跨域应用场景

实现方式:两个页面都经过js强制设置 document.domain为基础主域,就实现了同域

代码示例:

  1. 父窗口:http://www.domain1.com/a.html
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>
复制代码
  1. 子窗口:http://child.domain2.com/b.html
<script>
    document.domain = 'domain.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' + window.parent.user);
</script>
复制代码

5. CORS

普通跨域请求:只服务端设置Access-Control-Allow-Origin便可,前端无须设置

6. WebSocket协议跨域

前端代码示例

<div>user input:<input type="text"></div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>

<script>
var socket = io('http://www.domain2.com:8080');

// 链接成功处理
socket.on('connect', function() {
    // 监听服务端消息
    socket.on('message', function(msg) {
        console.log('data from server: ---> ' + msg); 
    });

    // 监听服务端关闭
    socket.on('disconnect', function() { 
        console.log('Server socket has closed.'); 
    });
});

document.getElementsByTagName('input')[0].onblur = function() {
    socket.send(this.value);
};
</script>
复制代码

参考文章:

前端常见跨域解决方案

相关文章
相关标签/搜索