• 常用跨域方法实践(一)


    这几天看了鬼道师兄的《跨终端Web》这本书,该书从解决实际业务出发,讲述了跨终端的优势与未来,受益良多。其中,书中第九章介绍了作者在阿里内部的一个参赛作品Storage,该作品巧妙的使用了跨域知识,让我见识到跨域其实不仅仅是JSONP。以前,对前端跨域这块或多或少有点了解,但真正动手实践的不是很多。于是,这段时间我好好整理了常用跨域方法的具体实现。本文,主要介绍了JSONPCORS的实现方式。

    相关概念:

    • 只要协议、域名、端口有任何一个不同,都被当作是不同的域
    • JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象
    • 跨域简单地理解就是因为JavaScript同源策略的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象

    注意:

    • 如果是协议和端口造成的跨域问题“前台”是无能为力的
    • 在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上(“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”)

    相关配置:为了演示效果,在hosts文件里面添加如下内容

    127.0.0.1 www.myapp.com  
    127.0.0.1 sample.myapp.com  
    127.0.0.1 www.otherapp.com  
    

    注意:测试demo基于NodeJSExpress4.X框架,且端口设置为80

    JSONP

    JSONP也叫填充式JSON,是应用JSON的一种新方法,只不过是被包含在函数调用中的JSON(如:callback({"name", "chenjun"});)。JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据

    跨域原理:利用<script>标签没有跨域限制,实现跨域目的

    访问页面:jsonp_test.ejs

      <script>
        function dosomething(jsondata) {
          alert(jsondata.name + " " + jsondata.age);
        }
      </script>
      <script src="http://www.otherapp.com/jsonp_data?callback=dosomething"></script>
    

    后台路由:index.js

    /* JSONP Test */
    router.get('/jsonp_test', function(req, res) {  
      res.render('jsonp/jsonp_test');
    });
    
    router.get('/jsonp_data', function(req, res) {  
      var callback = req.query.callback;
      var data = { name: "chenjun", age: "25" };
      var str =  callback + '(' + JSON.stringify(data) + ')'; //jsonp
      res.end(str);
    });
    

    效果:jsonp-test

    JSONP优缺点:

    • 优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行;并且在请求完毕后可以通过调用callback的方式回传结果
    • 缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JS调用的问题

    CORS

    CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。

    跨域原理:CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败

    浏览器支持情况:

    • Chrome 3+
    • Firefox 3.5+
    • Opera 12+
    • Safari 4+
    • Internet Explorer 8+

    Chrome,Firefox,Opera和Safari都使用XMLHttpRequest2对象。 Internet Explorer使用了类似的XDomainRequest对象,其工作原理和XMLHttpRequest大致相同,但增加了额外的安全预防措施。

    访问页面:cors_test.ejs

        // 创建XHR 对象.
        function createCORSRequest(method, url) {
          var xhr = new XMLHttpRequest();
          if ("withCredentials" in xhr) {
            // XHR for Chrome/Firefox/Opera/Safari.
            xhr.open(method, url, true);
          } else if (typeof XDomainRequest != "undefined") {
            // XDomainRequest for IE.
            xhr = new XDomainRequest();
            xhr.open(method, url);
          } else {
            // 不支持CORS.
            xhr = null;
          }
          return xhr;
        }
    
        // 发起CORS请求
        function makeCorsRequest() {
          var url = 'http://www.otherapp.com/cors_data';
          var xhr = createCORSRequest('GET', url);
          if (!xhr) {
            alert('CORS not supported!');
            return;
          }
    
          // 响应处理
          xhr.onload = function() {
            var text = xhr.responseText;
            alert(text);
          }
          xhr.onerror = function() {
            alert('Woops, there was an error making the request.');
          }
    
          xhr.send();
        }
    
        makeCorsRequest();
    

    后台路由:index.js

    /* CORS Test */
    router.get('/cors_test', function(req, res) {  
      res.render('cors/cors_test');
    });
    
    router.get('/cors_data', function(req, res) {  
      var data = { name: "chenjun", age: "25" };
      // 设置响应头
      res.setHead('Access-Control-Allow-Origin', '*');
      res.end(JSON.stringify(data));
    });
    

    效果:cors-test

    CORS优缺点:

    • 优点:支持所有类型的HTTP请求;使用普通的XMLHttpRequest发起请求和获得数据,拥有良好的出错处理
    • 缺点:老式浏览器不支持

    结语

    测试源码请戳这!下面一篇文章将介绍document.domainURL.hashcross-fragmentwindow.namepostMessage这五种方式的跨域实现。

    参考

     
  • 相关阅读:
    python中zip函数
    python中创建列表、元组、字符串、字典
    python中enumerate函数
    python中字符串的拼接
    python中格式化浮点数及科学计数法
    python中tuple函数
    python中可迭代对象的排序
    python中变量类型转换
    python中可迭代对象反转
    python中list函数
  • 原文地址:https://www.cnblogs.com/daqianduan/p/4625536.html
Copyright © 2020-2023  润新知