跨域通信方式

 1.什么是同源策略和限制?

同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互;所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。

限制:这个源的文档没有权利去操作另一个源的文档。这个限制体现在:Cookie、LocalStorage和IndexDB无法获取。

  • 无法获取和操作DOM。

  • 不能发送Ajax请求。我们要注意,Ajax只适合同源的通信。

2.前后端如何通信?

ajax、websocket和cors

ajax同源通信, websocket不限制同源通信, CORS支持跨域,也支持同源通信。

2.1 如何创建ajax?

  • XMLHttpRequest 的工作原理

  • 兼容性处理(XMLHttpRequest只有在高级浏览器中才支持。)

  • 事件的触发条件

  •  事件的触发顺序

  • 当请求一切正常时,相关的事件触发顺序如下:
    1.触发xhr.onreadystatechange(之后每次readyState变化时。都会触发一次)
    2.触发xhr.onloadstart
    上传阶段开始:
    3.触发xhr.upload.onloadstart
    4.xhr.upload.onprogress
    5.xhr.upload.onload
    6.xhr.upload.onloadend
    上传结束,下载阶段开始
    7.xhr.onprogress
    8.xhr.onload
    9.xhr.onloadend

XMLHttpRequest有很多触发事件,每个事件是怎么触发的。

2.2发送 Ajax 请求的五个步骤(XMLHttpRequest的工作原理)

(1)创建XMLHttpRequest 对象。 

  var  xhr= new XMLHttpRequest();

(2)使用open方法设置请求的参数。open(method, url, 是否异步)。

  

//设置请求的参数。包括:请求的方法、请求的url
 xhr.open('get','url');
 xhr.open('post','url');

(3)发送请求。

//get方法发送请求
  xhr.send()

//post 方法发送请求
// 如果想要使用post提交数据,必须添加此行
  xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
  xhr.send('name=zhangsan&age=19');

(4)注册事件。 注册onreadystatechange事件,状态改变时就会调用。

 // 发送并接受返回值
    xhr.onreadystatechange = function (){
          // 这步为判断服务器是否正确响应
          if (xhr.readyState = 4 && xhr.status == 200){

              // 获取返回的数据,更新dom
               response = xhr.responseText
          }
     }

 如果要在数据完整请求回来的时候才调用,我们需要手动写一些判断的逻辑。

(5)获取返回的数据,更新UI。

2.3 onreadystatechange 事件

注册 onreadystatechange 事件后,每当 readyState 属性改变时,就会调用 onreadystatechange 函数。

readyState:(存有 XMLHttpRequest 的状态。从 0 到 4 发生变化)

  • 0: 请求未初始化

  • 1: 服务器连接已建立

  • 2: 请求已接收

  • 3: 请求处理中

  • 4: 请求已完成,且响应已就绪

2.4 原生ajax请求

 // 原生ajax请求
    var util = {}
    // 获取ajax请求之后的json
    util.json = function (options){
        var opt = {
            url:'',
            type:'get',
            data:{},
            success:function (){

            } ,
            error:function (){

            },
        }
        util.extend(opt,options);
        if (opt.url){
            //IE兼容性处理:浏览器特征检查。检查该浏览器是否存在XMLHttpRequest这个api,没有的话,就用IE的api
            var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');
            var data = opt.data,
                url = opt.url,
                type = opt.type.toUpperCase(),
                dataArr = [];
        }
        for (var key in data){
            dataArr.push(key+'='+ data[key]);
        }
        if (type == 'GET'){
            url = url +'?'+dataArr.join('&')
            xhr.open(type,url.replace(/\?$/g,''),true)
            xhr.send()
        }
        if (type === 'POST'){
            xhr.open(type,url,true);
            // 如果想要使用post提交数据,必须添加此行
            xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
            xhr.send(dataArr.join('&'));
        }
        xhr.onload = function (){
            if (xhr.status === 200 || xhr.status === 304){
                // 304 :客户端请求服务器,服务器表示有缓存可用。 206表示获取媒体资源的一部分。
                var res;
                if (opt.success && opt.success instanceof  Function){
                    res = xhr.responseText;
                    if (typeof res === 'string'){
                        res = JSON.parse(res)  //将字符串转成json
                        opt.success.call(xhr,res)
                    }
                }
            } else {
                if (opt.error && opt.error instanceof Function){
                    opt.error.call(xhr,res);
                }
            }
        }
    }

3.跨域通信的几种方式?

jsonp、hash、postMessage、websocket、cors

ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。

3.1 jsonp

基本原理: 主要就是利用了 script 标签的src没有跨域限制来完成的

// 创建一个jsonpCallback函数。但是它还没有被调用
// 加载src中的资源,并等待请求的内容返回
<script type='text/javascript'>
    window.jsonpCallback = function (res) {
        console.log(res)
    }
</script>
<script src='http://localhost:8080/api/jsonp?id=1&callback=jsonpCallback' type='text/javascript'></script>

3.2 WebSocket


    var ws = new WebSocket('wss://'); //创建WebSocket的对象。参数可以是 ws 或 wss,后者表示加密。

    // 方法在连接成功时,触发
    ws.onopen = function (evt) {
        console.log("websocket连接成功");
      
    };
   // 监听连接失败
   ws.onerror = function(){
     console.log("连接失败...");
     // 重新连接
   }
    // message 事件会在 WebSocket 接收到新消息时被触发。
    ws.onmessage = function (data) {
     console.log("收消息onmessage---", data);
       
    };

    //WebSocket.close() 方法关闭 WebSocke连接或连接尝试(如果有的话)。 如果连接已经关闭,则此方法不执行任何操作。
    ws.onclose = function (evt) {
        console.log('close.');
    };

3.3、CORS

CORS 可以理解成是既可以同步、也可以异步*的Ajax。

fetch 是一个比较新的API,用来实现CORS通信。用法如下:

cors支持跨域通信:跨域时,浏览器会拦截Ajax请求,并在http头中加Origin。

3.4.hash

url的#后面的内容就叫Hash。Hash的改变,页面不会刷新。这就是用 Hash 做跨域通信的基本原理。

补充:url的?后面的内容叫Search。Search的改变,会导致页面刷新,因此不能做跨域通信。

页面A中:

  
    var B = document.getElementsByTagName('iframe');
    B.src = B.src + '#' + 'jsonString';  //我们可以把JS 对象,通过 JSON.stringify()方法转成 json字符串,发给 B

B页面中:


    window.onhashchange = function () {  //通过onhashchange方法监听,url中的 hash 是否发生变化
        var data = window.location.hash;
    };

5.postMessage

postMessage 推送 ,window.addEventListener接收使用

发送方使用postMessage方法向接收方推送消息,第一个参数为推送的内容,第二个参数是允许被访问的域名;

接收方通过window.addEventListener监听message的方法接收数据。

iframe引入页面(我也是使用这样方式)

在A页面中通过iframe的src放b页面的访问地址

 // url是需要接收传递消息的地址
   <iframe id="IframeTest"
            src="${url}"
            height="100%" width="100%" style="border: none">
   </iframe>

A页面获取iframe,发送消息

 // http://localhost:8000/#/ 是限制通信的具体地址,*代表是不限制地址
 var iframe = document.getElementById("IframeTest")
            iframe.contentWindow.postMessage({
                text:'消息内容',
                text2: '内容2'  // action : 自定义动作参数,用于接受收消息是的判断
             }, 'http://localhost:8000/#/');

若A页面也需要B 页面传过来的数据,

 //这是接收子页面返回的监听(如果只父页面发送消息不需要在接收子页面的反馈可以不用写这些)
     window.addEventListener('message', function (e) {
            alert(e.data)
            const data = e.data;
            console.log('子页面传过来的消息')
        }) 

B页面中(子页面中)

// 若是vue页面,可以写在mounted中接收
 window.addEventListener('message', (e) => {
      console.log(e)
      let data= e.data //这就是接收到的数据
      
   })

若在B页面需要给A页面传信息,触发A页面的

window.top.postMessage('{"text":"这是子页面传出去的信息", '*')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 中跨域解决方式有以下几种: 1. 通过服务端配置 CORS(跨域资源共享):在服务端的响应头中设置 `Access-Control-Allow-Origin` 字段,允许指定的域进行跨域访问。这种方式需要服务端的支持,如果你是自己搭建的服务端,可以参考以下示例代码: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/api') def api(): response = jsonify({'hello': 'world'}) # 允许指定的域进行跨域访问 response.headers['Access-Control-Allow-Origin'] = 'http://localhost:8080' return response if __name__ == '__main__': app.run() ``` 2. 通过代理解决跨域问题:在 Vue 的 `config/index.js` 中配置代理,将请求转发到本地的服务端,再由服务端进行真正的请求。这种方式不需要服务端的支持,但需要在本地搭建一个服务端。示例代码如下: ```javascript module.exports = { dev: { proxyTable: { '/api': { target: 'http://localhost:5000', // 本地的服务端地址 changeOrigin: true, pathRewrite: { '^/api': '/api' // 将请求的 /api 前缀转发到本地的 /api 路径 } } } } } ``` 3. JSONP(JSON with Padding)跨域:通过动态创建 `script` 标签来访问服务端接口,服务端返回的数据需要用一个函数包裹,以便在客户端中执行。这种方式只支持 GET 请求,并且需要服务端的支持。示例代码如下: ```javascript const script = document.createElement('script') script.src = 'http://example.com/api?callback=handleResponse' document.body.appendChild(script) function handleResponse(response) { console.log(response) } ``` 4. WebSocket 跨域:通过 WebSocket 协议进行双向通信,不受同源策略的限制。这种方式需要服务端的支持,并且需要在客户端和服务端都进行相应的配置。示例代码如下: ```javascript const socket = new WebSocket('ws://example.com/socket') socket.onopen = function(event) { console.log('WebSocket 已连接!') socket.send('Hello WebSocket!') } socket.onmessage = function(event) { console.log('收到消息:', event.data) } socket.onclose = function(event) { console.log('WebSocket 已关闭!') } ``` 以上是 Vue 中跨域解决方式的一些常见示例,具体的解决方案需要根据实际情况进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值