Skip to content

什么是同源策略及限制

同源策略限制从一个源(协议、域名和端口)加载的文档或脚本如何与来自另一个源的资源进行交互 这是一个用于隔离潜在恶意文件的关键的安全机制

  • Cookie、LocalStorage和IndexDB无法读取
  • DOM无法获得
  • Ajax请求不能发送

前后端如何通信

  • Ajax
  • WebSocket(不受同源策略限制)
  • CORS(支持跨域)

如何创建Ajax

  • XMLHttpRequest对象的工作流程
  • 兼容性处理
  • 事件的触发条件
  • 事件的触发顺序

跨域通信的几种方式

  • JSONP
  • Hash
  • postMessage
  • WebSocket
  • CORS
js
// 利用hash,场景是当前页面A通过iframe或frame嵌入了跨域的页面B
// 在A中伪代码如下:
const B = document.getElementsByTagName('iframe')
B.src = `${B.src}#` + 'data'
// 在B中的伪代码如下
window.onhashchange = function () {
  const data = window.location.hash
}
js
// postMessage
// 窗口A(http:A.com)向跨域的窗口B(http://B.com)发送信息
Bwindow.postMessage('data', 'http://B.com')
// 在窗口B中监听
Awindow.addEventListener('message', (event) => {
  console.log(event.origin)
  console.log(event.source)
  console.log(event.data)
}, false)
js
// Websocket
const ws = new WebSocket('wss://echo.websocket.org')

ws.onopen = function (evt) {
  console.log('Connectio open ...')
  ws.send('Hello WebSocket')
}

ws.onmessage = function (evt) {
  console.log(`Received Message: ${evt.data}`)
}

ws.onclose = function (evt) {
  console.log('Connection closed')
}
js
var util

// 注意!!!!!代码有缺省,代码不完整

util.jsonp = function (url, success, onerror, charset) {
  var callbackName = util.getName('tt_player')
  window[callbackName] = function () {
    if (onsuccess && util.isFunction(onsuccess)) {
      onsuccess(arguments[0])
    }
  }
  var script = util.createScript(url + '&callback=' + callbackName, charset)
  script.onload = script.onreadystatechange = function () {
    if (!script.readyState || /loaded|complete/.test(script.readyState)) {
      script.onload = script.onreadystatechange = null
      // 移除该script的DOM对象
      if (script.parentNode) {
        script.parentNode.removeChild(script)
      }
      // 删除函数或变量
      window[callbackName] = null
    }
  }
  script.onerror = function () {
    if (onerror && util.isFunction(onerror)) {
      onerror()
    }
  }
  document.getElementByTagName('head')[0].appendChild(script)
}

// 请求
util.json = function (options) {
  var opt = {
    url: '',
    type: 'get',
    data: {},
    success: function () { },
    error: function () { },
  }
  util.extend(opt, options)
  if (opt.url) {
    var xhr = XMLHttpRequest ? new XMLHttpRequest() : new Window.ActiveXObject('Microsoft.XMLHTTP')
    var data = opt.data,
      url = opt.url,
      type = opt.type.toUpperCase(),
      dataArr = [];
    for (var k in data) {
      dataArr.push(k + '=' + data[k])
    }
    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 === 304) {
        var res;
        if (opt.success && opt.success instanceof Function) {
          res = xhr.responseText
          if (typeof res === 'string') {
            res = JSON.parse(res)
            opt.success.call(xhr, res)
          }
        }
      } else {
        if (opt.error && opt.error instanceof Function) {
          opt.error.call(xhr, res)
        }
      }
    }
  }
}

export default util