前端通信

188 阅读2分钟

什么是同源策略及限制?

概念:同源策略限制从一个加载源的文档或者脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关健机制。

源的概念:有协议名,域名,端口组成(默认端口是80)。

如果源中有一项是不同的,那么就是源不一样就是跨域。 

限制:不是一个源的文档是不可以操纵两一个源的文档。

        主要限制在一下几个方面:

  • cookie、localstorage、indexDB 无法读取
  • DOM 无法获得
  • AJAX 请求不能发送

前后端如何通信?

  • ajax 同源通信
  • WebSocket  不受同源策略的限制
  • CROS 同源与不同源都可以通信

如何创建一个Ajax?

考察点:

  • XMLHttpRequest 对象的工作流程
  • 兼容性处理 
    只有高版本的浏览器才支持 XMLHttpRequest ,ie 不支持,以及火狐也不支持。
  • 事件的出发条件
  • 事件的出发顺序

    function ori_xml() {      var opt = {        url: "",        type: "get",        success: function () { },        error: function () { },      }      // 浏览器特征检查   生命对象,兼容ie      var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');      var data = opt.data,        url = OPT.url,        type = opt.type.toUpperCase(),        dataArr = [];      for (var i in data) {        dataArr.push(i + '=' + data[i]);      };      if (type === 'GET') {        url = url + '?' + dataArr.join('&');        xhr.open(type, url.replace(/\?$/g, ''), true);        xhr.send();      };      if (type === 'POST') {        xhr.open(type, url, true);        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');        xhr.send(dataArr.join('&'))      };      xhr.onload = function () {        if (xhr.status === 200 || xhr.status === 400) {          var res;          if (opt.success && opt.success instanceof Function) {            res = xhr.responseText;            if (typeof res === 'string') {              res = JSON.parse(res);              opt.success.cal(xhr, res)            }          }        } else {          if (opt.error && opt.error instanceof Function) {            opt.error.call(xhr, res)          }        }      }    }
    

跨域通信方式

  • JSONP
  • Hash 
    url中井号(#)后面的东西,hash 发生变化,页面不刷新 
    url 中 search问号(?)后面的东西发生改变是需要刷新页面的,所以不可以跨域通信
  • postMessage
  • WebSocket
  • CORS 
    理解为支持跨域同通信的ajax,浏览器中如何检测一个ajax跨域通信那么会自动为ajax添加origin头,否则会被拦截。

jsonp

通过script标签的异步加载完成

hash

利用hash,场景是当前页面a通过iframe或者frame嵌入跨域页面b

在a中的伪代码如下:

var B = document.getElementByTagName('iframe');

B.src = B.src + '#' + 'data';

在 b 中的伪代码如下:

window.onhashchange = function(){
     var data = window.location.hash;
}

  postMessage

窗口a向跨域窗口b发送消息

选中B页面的window
window.postMessage('data','http://B.com') // data 推荐使用字符串

在B窗口 中监听

window.addEventListener('message',function(event){
     console.log(event.orgin) // 从哪里来,判断发送者的源
     console.log(event.sourse) // 引用A 的 windw
     console.log(event.data) // data 数据
})

同理 b 给 a 也是一样。

WebSocket  参考学习

var ws = new WebSocket('网址');

ws.onopen = function (evt){
     console.log('connection open ... ')
     ws.send('hello!')
}

ws.message= function (evt){
     console.log('recieve message  ' + evt.data)
     ws.close('hello!')
}
ws.onclose= function (evt){
     console.log('connection close ... ')
}

 cros 学习参考

url 是必须的,options 是可选

fetch('/some/url',{
     methord:'get',
}).then(function (response){

}).catch(function(err){
     // 出错了;等价于then的第二个参数,但是这样更加好用
})