您现在的位置是:首页 >程序人生 >WEB前端

原生JS实现跨域问题-通过jsonp跨域

发布时间:2019-03-13 编辑:jielin 浏览:14744 评论:0

    jsonp跨域是比较常用的的一种跨域方式,使用跟理解都很简单,下面将通过一个小demo来讲解如何使用jsonp来跨域的

    这里简单的介绍jsonp的跨域原理:

    JSONP(JSON with Padding) 是一种跨域请求方式。主要原理是利用了script 标签可以跨域请求的特性,由其 src 属性发送请求到服务器,服务器返回 JavaScript 代码,浏览器接受响应,然后就直接执行了,这和通过 script 标签引用外部文件的原理是一样的。

    JSONP由两部分组成:回调函数和数据,回调函数一般是在浏览器控制,作为参数发往服务器端(当然,你也可以固定回调函数的名字,但客户端和服务器端的名称一定要一致)。当服务器响应时,服务器端就会把该函数和数据拼成字符串返回。 


    JSONP的请求过程:

    请求阶段:浏览器创建一个 script 标签,并给其src 赋值(类似 https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=18878556063&callback=fn...)。

    发送请求:当给script的src赋值时,浏览器就会发起一个请求。

    数据响应:服务端将要返回的数据作为参数和函数名称拼接在一起(格式类似”jsonpCallback({name: 'abc'})”)返回。当浏览器接收到了响应数据,由于发起请求的是 script,所以相当于直接调用 jsonpCallback 方法,并且传入了一个参数。

    下面将用一个获取电话号码归属地信息的案例来讲解jsonp的跨域原理

    html源代码:

     

    <div class="container">

        <div class="tel">

            <div class="title">号码归宿地查询</div>

            <div class="tel-inp">

                <div class="left"> 手机号码</div>

                <div class="right">

                    <input type="text" class="number" placeholder="电话号码">

                   <input type="button" class="search" value="查询">

                </div>

            </div>

            <div class="tel-info">

                <table>

                    <caption>查询结果</caption>

                    <tr>

                        <td>号码</td>

                        <td class="telString">***</td>

                     </tr>

                     <tr>

                        <td>号码段</td>

                       <td class="mts">***</td>

                     </tr>

                     <tr>

                         <td>归属地</td>

                        <td class="province">***</td>

                     </tr>

                     <tr>

                         <td>卡类型</td>

                        <td class="catName">***</td>

                    </tr>

        </table>

        </div>

      </div>

    </div>

    css样式:

     

    <style type="text/css">

    * {margin: 0; padding: 0;}

    body {

    font-size: 13px;

    }

    .container {

    max-width: 360px;

    margin: 0 auto;

    }

     

    .clearfix::before,

    .clearfix::after {

    content: "";

    display: table;

    }

     

    .clearfix::after {

    clear: both;

    }

     

    .title {

    font-size: 18px;

    width: 100%;

    height: 30px;

    height: 30px;

    line-height: 30px;

    text-align: center;

    border-bottom: 1px solid #ddd;

    margin-bottom: 10px;

    margin-top: 5%;

    }

     

    input {

    outline: none;

    }

     

    input[type="text"] {

    border: 1px solid #ddd;

    width: 70%;

    height: 25px;

    margin-left: 2%;

    text-indent: 10px;

    }

     

    input[type="button"] {

    width: 20%;

    height: 28px;

    cursor: pointer;

    color: #fff;

    background: rgb(102, 153, 204);

    border: 1px solid rgb(102, 153, 204);

    border-radius: 2px;

    }

     

    .tel-inp {

    height: 45px;

    line-height: 45px;

    border: 1px solid rgb(102, 153, 204);

    margin-bottom: 10px;

    border-radius: 2px;

    }

     

    table {

    width: 100%;

    border: 1px solid rgb(102, 153, 204);

    border-collapse: collapse;

        border-spacing: 0;

    }

     

    table tr {

    width: 100%;

    height: 30px;

    line-height: 30px;

    }

     

    table caption {

    width: 100%;

    height: 40px;

    line-height: 40px;

    background: rgb(102, 153, 204);

    color: #fff;

    border: 1px solid rgb(51, 102, 204);

    border-bottom: 0;

    box-sizing: border-box;

    }

     

    table tr td {

    width: 50%;

    text-align: center;

    border: 1px solid rgb(51, 102, 204);

    }

     

    .left {

    width:35%;

    float: left;

    text-align: center;

    border-right: 1px solid rgb(102, 153, 204);

    -webkit-box-sizing: border-box;

    -moz-box-sizing: border-box;

    box-sizing: border-box;

    }

     

    .right {

    width: 65%;

    float: right;

    }

    </style>

    js部分:

    <script type="text/javascript">

        // 这里定义一个函数接收API返回的数据,然后赋值给对应的dom

        function dataCallBack(data) {

            console.log(data);

            var province = document.querySelector(".province");

            var catName = document.querySelector(".catName");

            var mts = document.querySelector(".mts");

            var telStr = document.querySelector(".telString");

            province.innerHTML = data.province;

            catName.innerHTML = data.catName;

            mts.innerHTML = data.mts;

            telStr.innerHTML = data.telString;

       }

    </script>

     

    // 这里创建一个jsonp请求

    <script type="text/javascript">

            function TelSearch() {

                this.telString = document.querySelector(".telString");

                this.btn = document.querySelector(".search");

                this.num = document.querySelector(".number");

                this.mts = document.querySelector(".mts");

                this.province = document.querySelector(".province");

                this.catName = document.querySelector(".catName");

                this.reg = /^1(3|4|5|7|8)\d{9}$/;

                return this.init();

            }

     

            TelSearch.prototype = {

                constructor: TelSearch,

                 init: function() {

                    this.getData();

                },

                getData: function() {

                    var that = this;

                   this.btn.onclick = function() {

                       if (that.num.value === '') {

                          alert('号码不能为空!');

                         return;

                      }

                     if (!that.reg.test(that.num.value)) {

                         alert('号码格式错误!');

                         that.num.value = "";

                         return;

                   }

                  // 如果以上条件都符合则创建script标签并加入到页面中,其中https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=(号码)为接口,&callback=dataCallBack的dataCallBack为上面创建的函数,用来接收服务端返回的,指定回调函数为dataCallBack。

                  var script = document.createElement("script");

                  script.src = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=" + that.num.value + "&callback=dataCallBack";

                  document.body.appendChild(script);

                  that.num.value = "";

                 }

             }

         }

         // 执行该函数

         var t = new TelSearch;

    </script>

    注意:因为 script 标签的 src 属性只在第一次设置的时候起作用,导致 script 标签没法重用,所以每次完成操作之后要移除;