通信相关

163 阅读3分钟

同源策略及限制

  • 限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

同源的定义:

如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。

  • 限制了不同源之间Cookie,LocalStorage,indexDB的读取,DOM的获取,Ajax请求

前后端如何通信

  • Ajax
  • WebSocket
  • CORS( 跨域HTTP请求,web字体,WebGl贴图,样式表,使用 drawImage 将 Images/video 画面绘制到 canvas

创建Ajax

var xhr;
if (window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xhr=new XMLHttpRequest();
}
else{
    // IE6, IE5 浏览器执行代码
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    return success(xhr.responseText) //成功回调
  } else {
    return fail(xhr.status) //失败回调
  }
}
}
//GET
xhr.open("GET",URl+'?'+data,true)
xhr.send()

//POST
xhr.open("POST",URL,true)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
xhr.send(data)

跨域通信的几种方式

  • JSONP
function jsonp(url, jsonpCallback, success) {
  window[jsonpCallback] = function(data) {
    success && success(data)
  }

  var script = document.createElement('script')
  script.src = url + '&callback=' + jsonCallback
  script.async = true
  script.type = 'text/javascript'

  document.getElementByTagName('head')[0].appendChild(script)
}
jsonp(请求URL, 回调函数名, 回调函数fn)

全局注册window[jsonpCallback],通过在JSONP请求地址后加上&callback="回调函数名字",请求成功后返回数据为callbackFunction(data),之后调用该回调函数就可拿到数据。

  • Hash

hash改变不刷新页面

// pageA通过iframe嵌入了pageB
var B = document.getElementByTagName('iframe')
B.src = B.src + '#' + 'data'

// pageB中的代码
window.onhashchange = function (data) {
  data = window.location.hash    //  <-  pageB就获取到了hash值
}
  • postMessage //h5

MDN

// pageA通过iframe嵌入了pageB
// pageA中代码
window.iframe[i].postMessage('data','pqgeB的URL')
// pageB中的代码
window.addEventListener('message',funciton(e){
  console.log(e.data)     // data
  console.log(e.source)   // a中window的引用
  console.log(e.oringin)  // pageA的URL
},false)

// 反过来pageB向pageA发送数据
// 在pageA中加入window.addEventListener
// 在pageB中e.source.postMessage

  • WebSocket
function WebSocket1() {
      if ("WebSocket" in window) {    // 判断浏览器支持
        var ws = new WebSocket(请求URl);

        ws.onopen = function (evt) {
          ws.send(发送的数据);
        }
        ws.onmessage = function (evt) {
          console.log('收到数据' + evt.data)
          ws.close()   //  <-  关闭连接
        }
        ws.onclose = function () {
          console.log('连接关闭')
        }
      }
    }
    WebSocketTest()
  • CORS

跨域资源共享 CORS 详解 - 阮一峰

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。 当浏览器监测到跨域的ajax请求时,会在http头部添加

Access-Control-Allow-Origin:指定授权访问的域

Access-Control-Allow-Methods:授权请求的方法(GET, POST, PUT, DELETE,OPTIONS等)

fetch-->改变mode的参数即可实现跨域) MDN 使用fetch

fetch与ajax的不同

  • 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。

  • 默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。

fetch('URL',{
  ...  //此处可传入 headers,body,catch等,详见https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
  method: 'GET',
})then(function(res){
  if(res.ok) {
    // 检测请求是否成功
  }
  throw new Error('Network response was not ok.');
}).catch(function(err){

})