最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 跨域请求的几种方式(二)

    正文概述 掘金(Yuhior)   2021-04-23   502

    postMessage

    window.postMessage()是HTML5的一个接口,专注实现在不同窗口不同页面的跨域通信。 用法:postMessage(data,origin) 参数:

    • data:html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
    • origin:协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
    1. a.html:(www.dotest1.com/a.html)
    <iframe id="iframe" src="http://www.dotest2.com/b.html" style="display:none;"></iframe>
    <script>
        var iframe = document.getElementById('iframe');
        iframe.onload = function() {
            var data = {
                name: 'aym'
            };
            // 向dotest2传送跨域数据
            iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.dom2.com');
        };
    
        // 接受domain2返回数据
        window.addEventListener('message', function(e) {
            alert('data from dotest2 ' + e.data);
        }, false);
    </script>
    
    1. b.html:(www.dotest2.com/a.html)
    <script>
        // 接收domain1的数据
        window.addEventListener('message', function(e) {
            alert('data from dotest1 ---> ' + e.data);
    
            var data = JSON.parse(e.data);
            if (data) {
                data.number = 16;
    
                // 处理后再发回domain1
                window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
            }
        }, false);
    </script>
    

    CORS

    cors全称是“跨域资源共享”(Cross-origin resource sharing),cors请求有两种请求,简单请求和非简单请求。 只要同时满足以下两大条件,就属于简单请求。

    1. 请求方法是以下三种方法之一
    • HEAD
    • GET
    • POST
    1. HTTP的头信息不超出以下几种字段
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

    普通请求只需要在服务端设置Access-Control-Allow-Origin即可,也就是告诉什么站点是被允许的。前端什么也不用干只需要正常的发送请求就好。

    res.writeHead(200, {
        'Access-Control-Allow-Origin': 'http://www.do1.com', // 允许访问的域(协议+域名+端口)
    });
    

    但是如果需要带cookie的话,前后端都需要进行设置

    前台

    • 原生ajax
    var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
    
    // 前端设置是否带cookie
    xhr.withCredentials = true;
    
    xhr.open('post', 'http://www.dotest2.com:8080/login', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('user=admin');
    
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };
    
    • jQueryajax:
    $.ajax({
        ...
       xhrFields: {
           withCredentials: true    // 前端设置是否带cookie
       },
       crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
        ...
    });
    
    • vue框架
    Vue.http.options.credentials = true
    

    后台

    • Node
    // 跨域后台设置
    res.writeHead(200, {
        'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
        'Access-Control-Allow-Origin': 'http://www.dotest1.com', // 允许访问的域(协议+域名+端口)
        /* 
         * 此处设置的cookie还是dotest2的而非dotest1,因为后端也不能跨域写cookie(nginx反向代理可以实现),
         * 但只要dotest2中写入一次cookie认证,后面的跨域接口都能从dotest2中获取cookie,从而实现所有的接口都能跨域访问
         */
        'Set-Cookie': 'l=a123456;Path=/;Domain=www.dotest2.com;HttpOnly' 
        // HttpOnly的作用是让js无法读取cookie
    });
    

    非简单请求:如果请求方法是PUT、DELETE,或者Content-type的类型为applicetion/json的。使用非简单请求 会发出一次预检测,返回码是204,预检测通过才会发送真正的请求

    • Node
    var allowCrossDomain = function(req, res, next) {
        res.header('Access-Control-Allow-Origin', 'http://localhost:63342');
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
        res.header('Access-Control-Allow-Headers', 'Content-Type,accept,X-Custom-Header');
        res.header('Access-Control-Allow-Credentials', 'true');
        next();
    };
    
    • 前端
    var url = 'http://www.domain2.com:8080/login';
    var xhr = new XMLHttpRequest();
    xhr.open('PUT', url, true);
    xhr.setRequestHeader('X-Custom-Header', 'value');
    xhr.send()
    

    上边代码中,HTTP请求方法是PUT,并且发送了一个自定义头信息X-Custom-Header。浏览器发现这是一个非简单请求 ,就会发出一个预检请求,要求服务器确认可以这样请求。

    代理

    跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。 **实现思路:**通过nginx配置一个代理服务器(域名与dotest1相同,端口不同)做跳板机,反向代理访问dotest2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

    1. nginx具体配置

    proxy服务器
    server {
        listen 81;
        server_name www.domain1.com;
    
        location / {
            proxy_pass http: //www.domain2.com:8080;  #反向代理
                proxy_cookie_domain www.domain2.com www.domain1.com;#修改cookie里域名
            index index.html index.htm;
    
            #当用webpack - dev - server等中间件代理接口访问nignx时, 此时无浏览器参与, 故没有同源限制, 下面的跨域配置可不启用
            add_header Access - Control - Allow - Origin http: //www.domain1.com;  #当前端只跨域不带cookie时,可为*
                add_header Access - Control - Allow - Credentials true;
        }
    }
    
    • 前端代码示例
    var xhr = new XMLHttpRequest();
    // 前端开关:浏览器是否读写cookie
    xhr.withCredentials = true;
    // 访问nginx中的代理服务器
    xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);
    xhr.send();
    
    • 后台Nodejs

    2. Nodejs中间件代理插件 这篇有详细说明详见

    WebSocket协议跨域

    WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。 原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。


    起源地下载网 » 跨域请求的几种方式(二)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元