原生JavaScript完成AJAX、JSONP

置信大多数前端开发者在须要与后端举行数据交互时,为了方便快捷,都邑挑选JQuery中封装的AJAX要领,然则有些时刻,我们只须要JQuery的AJAX要求要领,而其他的功用用到的很少,这显然是没必要的。

实在,原生JavaScript完成AJAX并不难,这篇文章将会解说怎样完成简朴的AJAX,另有跨域要求JSONP!

一、AJAX

AJAX的中心是XMLHttpRequest

一个完全的AJAX要求平常包含以下步骤:

  • 实例化XMLHttpRequest对象

  • 衔接服务器

  • 发送要求

  • 吸收相应数据

我将AJAX要求封装成ajax()要领,它接收一个设置对象params。

function ajax(params) {   

  params = params || {};   

  params.data = params.data || {};   

  // 推断是ajax要求照样jsonp要求

  var json = params.jsonp ? jsonp(params) : json(params);   

  // ajax要求   

  function json(params) {   

    //  要求体式格局,默许是GET

    params.type = (params.type || 'GET').toUpperCase(); 

    // 防备有特别字符,必需花样化传输数据  

    params.data = formatParams(params.data);   

    var xhr = null;    



    // 实例化XMLHttpRequest对象   

    if(window.XMLHttpRequest) {   

      xhr = new XMLHttpRequest();   

    } else {   

      // IE6及其以下版本   

      xhr = new ActiveXObjcet('Microsoft.XMLHTTP');   

    }; 



    // 监听事宜,只需 readyState 的值变化,就会挪用 readystatechange 事宜 

    xhr.onreadystatechange = function() {  

      //  readyState属性示意要求/相应历程的当前运动阶段,4为完成,已吸收到悉数相应数据

      if(xhr.readyState == 4) {   

        var status = xhr.status;  

        //  status:相应的HTTP状况码,以2开首的都是胜利

        if(status >= 200 && status < 300) {   

          var response = ''; 

          // 推断接收数据的内容范例  

          var type = xhr.getResponseHeader('Content-type');   

          if(type.indexOf('xml') !== -1 && xhr.responseXML) {   

            response = xhr.responseXML; //Document对象相应   

          } else if(type === 'application/json') {   

            response = JSON.parse(xhr.responseText); //JSON相应   

          } else {   

            response = xhr.responseText; //字符串相应   

          };  

          // 胜利回调函数 

          params.success && params.success(response);   

       } else {   

          params.error && params.error(status);   

       }   

      };   

    };  

  

    // 衔接和传输数据   

    if(params.type == 'GET') {

      // 三个参数:要求体式格局、要求地点(get体式格局时,传输数据是加在地点后的)、是不是异步要求(同步要求的状况少少);

      xhr.open(params.type, params.url + '?' + params.data, true);   

      xhr.send(null);   

    } else {   

      xhr.open(params.type, params.url, true);   

      //必需,设置提交时的内容范例   

      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 

      // 传输数据  

      xhr.send(params.data);   

    }   

  }  

 

  //花样化参数   

  function formatParams(data) {   

    var arr = [];   

    for(var name in data) { 

      //   encodeURIComponent() :用于对 URI 中的某一部份举行编码

      arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));   

    };   

    // 增加一个随机数参数,防备缓存   

    arr.push('v=' + random());   

    return arr.join('&');   

  }



  // 猎取随机数   

  function random() {   

    return Math.floor(Math.random() * 10000 + 500);   

  }

}

在上面的代码中,已增加详细的解释,如需相识更多AJAX,可检察博主的书本《JavaScript半知半解》中的AJAX章节:AJAX

运用实例:

ajax({   

  url: 'test.php',   // 要求地点

  type: 'POST',   // 要求范例,默许"GET",还可所以"POST"

  data: {'b': '异步要求'},   // 传输数据

  success: function(res){   // 要求胜利的回调函数

    console.log(JSON.parse(res));   

  },

  error: function(error) {}   // 要求失利的回调函数

});

二、JSONP

同源战略

AJAX之所以须要“跨域”,罪魁祸首就是浏览器的同源战略。即,一个页面的AJAX只能猎取这个页面雷同源或许雷同域的数据。 怎样叫“同源”或许“同域”呢?——协定、域名、端口号都必需雷同。比方:

http://example.com  和  https://example.com 差别,因为协定差别;   

http://localhost:8080  和  http://localhost:1000 差别,因为端口差别;   

http://localhost:8080  和  https://example.com 差别,协定、域名、端口号都差别,基础不是一家的。

当跨域要求时,平常都邑看到这个毛病:

XMLHttpRequest cannot load http://ghmagical.com/article/… No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost‘ is therefore not allowed access.

那怎样跨域要求呢?这时候,JSONP就上台了!

JSONP(JSON with Padding) 是一种跨域要求体式格局。重要道理是利用了script 标签能够跨域要求的特征,由其 src 属性发送要求到服务器,服务器返回 JavaScript 代码,浏览器接收相应,然后就直接执行了,这和经由过程 script 标签援用外部文件的道理是一样的。

JSONP由两部份构成:回调函数和数据,回调函数平常是在浏览器掌握,作为参数发往服务器端(固然,你也能够牢固回调函数的名字,但客户端和服务器端的称号一定要一致)。当服务器相应时,服务器端就会把该函数和数据拼成字符串返回。
JSONP的要求历程:

  • 要求阶段:浏览器建立一个 script 标签,并给其src 赋值(相似 http://example.com/api/?callb…)。

  • 发送要求:当给script的src赋值时,浏览器就会提议一个要求。

  • 数据相应:服务端将要返回的数据作为参数和函数称号拼接在一起(花样相似”jsonpCallback({name: ‘abc’})”)返回。当浏览器吸收到了相应数据,因为提议要求的是 script,所以相当于直接挪用 jsonpCallback 要领,而且传入了一个参数。

关于JQuery的JSONP要求,这里就不多讲了,之前也写过一篇文章《JQuery的Ajax要求跨域题目》。

在这里解说一下用原生JavaScript怎样完成。

依旧是ajax()要领里增加JSONP,背面会将二者整合在一起,JSONP的设置参数重要多了一个jsonp参数,它就是你的回调函数名。

function ajax(params) {   

  params = params || {};   

  params.data = params.data || {};   

  var json = params.jsonp ? jsonp(params) : json(params);      



  // jsonp要求   

  function jsonp(params) {   

    //建立script标签并加入到页面中   

    var callbackName = params.jsonp;   

    var head = document.getElementsByTagName('head')[0];   

    // 设置传递给背景的回调参数名   

    params.data['callback'] = callbackName;   

    var data = formatParams(params.data);   

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

    head.appendChild(script);    

 

    //建立jsonp回调函数   

    window[callbackName] = function(json) {   

      head.removeChild(script);   

      clearTimeout(script.timer);   

      window[callbackName] = null;   

      params.success && params.success(json);   

    };    



    //发送要求   

    script.src = params.url + '?' + data;    



    //为了得知此次要求是不是胜利,设置超时处置惩罚   

    if(params.time) {   

     script.timer = setTimeout(function() {   

       window[callbackName] = null;   

       head.removeChild(script);   

       params.error && params.error({   

         message: '超时'   

       });   

     }, time);   

    }   

  };    



  //花样化参数   

  function formatParams(data) {   

    var arr = [];   

    for(var name in data) {   

      arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));   

    };   



    // 增加一个随机数,防备缓存   

    arr.push('v=' + random());   

    return arr.join('&');   

  }   



  // 猎取随机数   

  function random() {   

    return Math.floor(Math.random() * 10000 + 500);   

  }
}

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

运用实例:

ajax({   

  url: 'test.php',    // 要求地点

  jsonp: 'jsonpCallback',  // 采纳jsonp要求,且回调函数名为"jsonpCallbak",能够设置为正当的字符串

  data: {'b': '异步要求'},   // 传输数据

  success:function(res){   // 要求胜利的回调函数

    console.log(res);   

  },

  error: function(error) {}   // 要求失利的回调函数

});

在这里背景运用PHP处置惩罚:

<?php

   $data = array('type'=>'jsonp');

   $callback = isset($_GET['callback']) ? trim($_GET['callback']) : '';  

   echo $callback.'('.json_encode($data).')';

注重:别漏了用函数名与数据拼接返回。

固然,前面也说过,你能够给定牢固回调函数名:

function jsonpCallback() {}


<?php 

  echo 'jsonpCallback('.$data.')';

末了我已将AJAX和JSONP要求合并在一起了,下载链接:ajax.zip

原文链接:原生JavaScript完成AJAX、JSONP

若有题目,迎接在下方留言!

    原文作者:TGCode
    原文地址: https://segmentfault.com/a/1190000008269816
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞