跨域解决方案与模板引擎

348 阅读2分钟

跨域

同源策略

  • 同源策略是浏览器的一种安全策略,所谓同源是指:域名、协议、端口完全相同
  • 同源或不同源说是两个地址之间的关系,不同源地址之间请求,称之为:跨域请求

同源(协议、域名、端口)

同源.png

问题

  • 在同源策略下,只有同源的地址才可以相互通过AJAX的方式请求。那怎么才能实现跨域请求呢?

跨域解决方案

JSONP原理

  • JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。
  • 原理:在客户端借助script标签请求服务端的一个的地址。
  • 地址返回: 一段带有某个全局函数调用的JavaScript脚本。
  • 在调用函数中,原本需要返回给客户端的数据 通过参数传递给这个函数。
  • 这样客户端的函数中就可以通过参数得到原本服务端想要返回的数据。

演示服务端

  • 图片展示 服务端演示.png

演示客户端

  • 图片展示

客户端演示.png

演示响应结果

  • 图片展示

响应结果.png

演示控制台结果

  • 图片展示

控制台结果.png

JSONP只能发送GET请求

  • JSONP用的是script标签,与AJAX提供的XMLHttpRequest没有任何关系。

jQuery中对JSONP的支持

  • jQuery基本使用$.ajax()

jQuery中使用JSONP

  • 将dataType设置为:JSONP(最常用)
  • 代码演示
$.ajax({
    url:"https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
    type:"GET",
    dataType:"JSONP",
    // 传递参数
    data:{
        "wd":"ajax"
    },
    success:function (data){
        // 返回一个对象
        console.log(data);
    }
});

设置

  • 可以根据后台的要求进行设置函数参数名称
  • jQ自动分配的回调函数的名称进行重命名
$.ajax({
    url:"https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
    type:"GET",
    dataType:"JSONP",
    // 这条属性可以设置回调函数的参数名称
    // 必须与后台接口的回调函数参数名保持一致
    jsonp:"cb",
    // jQ自动分配的回调函数的名称进行重命名
    jsonpCallback:"abc",
    // 传递参数
    data:{
        "wd":"ajax"
    },
    success:function (data){
        console.log(data);
    }
});

Axios没有封装jsonp

  • axios中没有封装jsonp的事件,故其用不了,推荐使用jquery中的方法执行。

CORS

  • Cross Origin Resource Share 跨域资源共享
  • 这种方案无需客户端做任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加 Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。
  • Access-Control-Allow-Origin值:
    • *表示允许任意源访问,不安全
    • foo.com 允许指定的源访问

服务端演示

  • 图片展示

CORS服务端演示.png

案例应用

模仿百度搜索案例

<!-- 搭建结构 -->
<div class="box">
    <div class="searchBox">
        <input type="text" name="" class="txt">
        <ul>
        </ul>
    </div>
    <input type="button" value="搜索" class="btn">
</div>
// 获取元素
var $ul = $(".searchBox ul");
var $txt = $(".txt");
$txt.keyup(function (){
    var $val = $txt.val();

    // 跨域请求
    $.ajax({
        url:"https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
        type:"GET",
        dataType:"jsonp",
        data:{
            "wd":$val
        },
        success:function (data){
            // 需要将从后台获取到的值,展示在前台
            var arr = data.g;
            // 方法1:字符串拼接
            var str = "";
            for(var i = 0; i < arr.length; i++){
                // str += "<li>"+ arr[i].q +"</li>";
                str += `<li>${arr[i].q}</li>`;
            }
            // 将拼接好的字符串 渲染到前端页面中
            $ul.html(str);
        }
});
});

模板引擎

作用

  • 减少字符串拼接
  • 在模板里面解析json,然后跟html内容拼接,性能会更好

artTemplate(腾讯)

常用语法:

  • <% 与 %> 符号包裹起来的语句则为模板的逻辑表达式
  • <%= content %>为输出表达式

artTemplate使用步骤

  • 引入模板文件
  • 创建模板
  • 将数据跟模板进行绑定
  • 绑定数据和模板之后得到内容
  • 将数据内容写到页面上面

代码演示

<script src="js/jquery.min.js"></script>
<!-- 第一步:引入模板文件 -->
<script src="js/template-native.js"></script>
<!-- 第二步:创建模板 -->
<script id="tem" type="text/html">
    <!-- 第三步:添加模板中的结构 -->
    <% for(var i = 0;i < 5; i++) { %>
        <div>这是第一个模板中的div<%= i%></div>
        <!-- 传递的对象,可以直接在里面使用属性 -->
        <div>这是第一个模板中的div2<%= name%></div>
    <% } %>
    <!-- 第四步:在模板中编写js代码解析数据 -->
</script>
<div class="box">
</div>
<script>
// 第五步:将数据跟模板进行绑定
// 参数1:调用模板的id 
    // 参数2:对象型的数据,数据会传给模板,
    //       对象中的每个属性的属性名在模板中可以直接当变量名使用
    var t = template("tem",{name:"zs"});
    // 第六步:将数据内容写在页面上
    $(".box").html(t);
</script>

优化百度搜索案例

  • 代码演示
<!-- 引入模板文件 -->
<script src="js/template-native.js"></script>
<!-- 创建模板 -->
<script id="tem" type="text/html">
    <!-- 可以直接写html标签 -->
    <% for(var i = 0; i < g.length; i++){ %>
        <li><%= g[i].q%></li>
    <% } %>
</script>
// 获取元素
var $ul = $(".searchBox ul");
var $txt = $(".txt");
$txt.keyup(function (){
    var $val = $txt.val();

    // 跨域请求
    $.ajax({
        url:"https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
        type:"GET",
        dataType:"jsonp",
        data:{
            "wd":$val
        },
        success:function (data){
            // 需要将从后台获取到的值,展示在前台
           // 绑定模板 传数据
           // 模板处理好的 返回字符串
           $ul.html(template("tem",data));
        }
});
});