常见问题:

  1. 什么是同源策略及限制
  2. 前后端如何通信
  3. 如何创建ajax
  4. 跨域通信的几种方式

同源策略:

定义:

  1. 源包括协议,域名,端口,只要有一个不一样就是不同的源
  2. 不是一个源的文档无权去操作另外一个源的文档

    具体表现:

  3. cookie,storage,indexDB无法读取

  4. DOM无法获得
  5. AJAX请求无法发送

    前后端如何通信:

  6. AJAX:同源通信

  7. websocket:不受同源策略的限制
  8. CORS:支持跨域通信和同源通信

如何创建一个ajax:

  1. xmlhttprequest对象的工作流程
  2. 兼容性处理
  3. 事件的触发条件
  4. 事件的触发顺序

跨域通信的几种方式:

jsonp

  1. 原理:script标签的异步加载
  2. 如何实现:

    1. 客户端向服务端发起请求,并告诉服务器端callback的名称<script src="http://www.baidu.com?data=name&callback=jsonpMethod"></script>
    2. 后端返回一个jsonp函数
      1. jsonpMethod({
      2. data:{
      3. }
      4. })
  3. 实现代码:

  1. var util={}
  2. util.getName=function(prefix){
  3. return prefix+Math.random().toString(36)
  4. .replace(/[^a-z]+/g,'').substr(0,5)
  5. }
  6. util.createScript=function(url,charset){
  7. var script=document.createElement('script')
  8. script.setAttribute('type','text/javascript')
  9. charset&&script.setAttribute('charset',charset)
  10. script.setAttribute('src',url)
  11. script.sync=true
  12. return script
  13. }
  14. util.jsonp=function(url, onsuccess, onerror, charset){
  15. // 告诉后端回调的名称
  16. var callbackName=util.getName('tt_player')
  17. // 在window注册一个全局callback
  18. window[callbackName]=function(){
  19. if (onsuccess && util.isFunction(onsuccess)) {
  20. onsuccess(arguments[0]);
  21. }
  22. }
  23. // 动态创建一个script标签
  24. var script=util.createScript(url+'&callback='+callbackName,charset)
  25. // 判断标签是否加载成功
  26. script.onload=script.onreadystatechange=function(){
  27. if(!script.readyState||/loaded|complete/.test(script.readyState)){
  28. script.onload=script.onreadystatechange=null
  29. // 移除该script的DOM对象
  30. if(script.parentNode){
  31. script.parentNode.removeChild(script)
  32. }
  33. // 删除函数或变量
  34. window[callbackName]=null
  35. }
  36. }
  37. script.onerror=function(){
  38. if(this.onerror&&util.isFunction(onerror)){
  39. this.onerror()
  40. }
  41. }
  42. document.getElementsByTagName("head")[0].appendChild(script)
  43. }

hash

  1. 场景:当前页面A通过iframe嵌入了跨域的页面B
  2. 代码:
    1. //A页面
    2. var B=document.getElementsByTagName('iframe')
    3. B.src=B.src+'#'+'data'
    4. //b页面添加以下代码
    5. window.onhashchange=function(){
    6. var data=window.location.hash
    7. }

postmessage

  1. 场景:窗口A向跨域的窗口B发送消息
  2. 代码(使用http-server在本地开启两个服务)

parent.html

  1. <h1>父窗口</h1>
  2. <iframe src="http://localhost:9001/child.html"
  3. width="500" height="100" frameborder="0"></iframe>
  4. <button name="button" id="send">发信息给子窗口</button>
  5. <script src="./parent.js"></script>

parent.js

  1. window.addEventListener('message',function(data){
  2. this.console.log("我是父窗口,收到了子窗口发过来的消息","vs",data)
  3. },false)
  4. var btn=document.getElementById("send")
  5. btn.addEventListener('click',function(e){
  6. let child=document.querySelector("iframe").contentWindow
  7. child.postMessage('这是父窗口发给你的信息','http://localhost:9001')
  8. })

child.html

  1. <h1>我是子页面</h1>
  2. <script src="./child.js" charset="utf-8"></script>

child.js

  1. window.addEventListener('message',function(data){
  2. console.log(data)
  3. window.parent.postMessage('子窗口给父窗口回复','http://localhost:9002')
  4. },false)

websocket

  1. var ws=new WebSocket('wss://echo.websocket.org')//ws是非加密,wss是加密
  2. ws.onopen=function(ev){
  3. console.log("connection 开始")
  4. ws.send('hello WebSockets!!!')
  5. }
  6. ws.onmessage=function(ev){
  7. console.log("收到消息"+ev.data)
  8. }
  9. ws.onclose=function(ev){
  10. console.log("connection 关闭")
  11. }

cors

  1. fetch(url,{
  2. method:'get'
  3. }).then(function(res){
  4. //对响应res进行处理
  5. }).catch(function(err){
  6. //对错误进行处理
  7. })
  1. 需要服务器和浏览器同时支持
  2. 仅支持IE10以上浏览器
  3. 浏览器一旦发现ajax跨域请求资源,就会自动添加一些附加的头信息
  4. 实现CORS通信的关键是服务器,服务器实现了CORS接口,就可跨源通信