码迷,mamicode.com
首页 > Web开发 > 详细

用原生JS实现AJAX和JSONP

时间:2018-05-04 21:23:59      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:lin   upper   需要   request对象   tor   res   type   input   error:   

 

前端开发在需要与后端进行数据交互时,为了方便快捷,都会选择JQuery中封装的AJAX方法,但是有些时候,我们只需要JQuery的AJAX请求方法,而其他的功能用到的很少,这显然是没必要的。其实,原生JavaScript实现AJAX并不难,下面我们可是演示如何实现利用原生JS构建简单的AJAX,还有跨域请求JSONP的实现。

AJAX的根本是XMLHttprequest,而一个完整的AJAX请求一般包括以下步骤:

  • 实例化XMLHttpRequest对象
  • 连接服务器
  • 发送请求
  • 接收响应数据

下面我们使用原生JS封装一个简单地ajax()方法:

 1  const Ajax = (object) => {
 2         object = object || {};
 3         object.data = object.data || {};
 4         //判断请求类型为AJAX或者JSONP
 5         let json = object.jsonp ? Jsonp(object) : ajax(object);
 6 
 7         //设置ajax方法
 8         function ajax(object) {
 9            // 1.设置请求方式:如果没有制定则默认为GET
10            object.type = (object.type || ‘GET‘).toUpperCase();
11            // 2.设置data数据的格式化
12            object.data = formateObject(object.data);
13            // 3.实例化XMLHttpRequest对象  
14            var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject(‘Microsoft.XMLHTTP‘);
15            // 4.监听事件,只要readyState改变,就会调用readystatechange事件
16            xhr.onreadystatechange = function(){
17                // readyState属性表示请求/响应过程的当前活动阶段,4为完成,已经接收到全部响应数据
18                if(xhr.readyState == 4) {
19                    let status = xhr.status;
20                    // status : HTTP响应的状态码,2开头表示成功
21                    if(status >=200 && status < 300){
22                        let response = ‘‘;
23                        // 判断接受数据的内容类型 
24                        let type = xhr.getResponseHeader(‘Content-type‘);  
25                        if(type.indexOf(‘xml‘) !== -1 && xhr.responseXML) {  
26                           response = xhr.responseXML; //Document对象响应  
27                          } else if(type === ‘application/json‘) {  
28                           response = JSON.parse(xhr.responseText); //JSON响应  
29                          } else {  
30                           response = xhr.responseText; //字符串响应  
31                         }; 
32                         // 成功回调函数 
33                         object.success && object.success(response);  
34                    }else {
35                         object.error && object.error(response);  
36                    }
37                }
38            }
39 
40            
41            // 5.连接和传输数据
42            if(object.type == ‘GET‘) {
43                // 三个参数:请求方式、请求地址(get方式时,传输数据是加在地址后的)、是否异步请求(同步请求的情况极少);
44                xhr.open(object.type, object.url + ‘?‘ + object.data, true);  
45                xhr.send(null);  
46             } else {  
47                xhr.open(object.type, object.url, true);  
48                //必须,设置提交时的内容类型  
49                xhr.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded; charset=UTF-8‘); 
50                // 传输数据 
51                xhr.send(object.data); 
52             }
53         }
54 
55             //data的格式化方法
56         function formateObject(data){
57            if(data){
58                let arr = [];
59                for(let name in data){
60                    //encodeURIComponent() :用于对 URI 中的某一部分进行编码
61                    arr.push(encodeURIComponent(name) + ‘=‘ + encodeURIComponent(data[name]));
62                }
63 
64                //为了防止缓存,在后面添加一个随机数
65                arr.push(‘randomV=‘ + randomNumber());
66                return arr.join(‘&‘);
67            }else {
68                console.error(‘无法格式化请求数据‘)
69            }
70         }
71 
72         //生成随机数的方法
73         function randomNumber(){
74             return Math.floor(Math.random()*10000+404);
75         }
76 
77     };


同理,我们也可以实现一个JSONP的方法

//设置Jsonp方法
        function Jsonp(object) {
          // 创建script标签并加入到页面中
          let callbackName = object.jsonp,
              head = document.getElementsByTagName(‘head‘)[0];
          // 设置传递给后台的回调参数名  
          object.data[‘callback‘] = callbackName;  
          let data = formateObject(object.data),
              script = document.createElement(‘script‘);  
          head.appendChild(script);  
          // 创建JSONP的回调函数
          //创建jsonp回调函数  
          window[callbackName] = function(json) {  
              head.removeChild(script);  
              clearTimeout(script.timer);  
              window[callbackName] = null;  
              object.success && object.success(json);  
          };  
          // 发送请求
          script.src = object.url + ‘?‘ + data;  
          //为了得知此次请求是否成功,设置超时处理  
          if(object.time) {  
           script.timer = setTimeout(function() {  
            window[callbackName] = null;  
            head.removeChild(script);  
            object.error && object.error({  
             message: ‘请求超时‘ 
            });  
           }, time);  
          }  

        }

下面我们来尝试一下这两个方法是否管用
新建一个index.html文件,新建一个test.json和jsonp.php

技术分享图片

 

利用nginx搭建一个简单地服务器,因为谷歌默认不允许本地文件进行ajax请求:

 

 

test.json内容

 

1 {
2    "name" : "111",
3    "gender" :  "222" 
4 }

 

jsonp.php内容:

 

callback({"name":"李大师","gender":"是前端开发工程师"})    

 

index.html内容

  1 <!doctype html>
  2 <html lang="en">
  3  <head>
  4   <meta charset="UTF-8">
  5   <meta name="Generator" content="EditPlus?">
  6   <meta name="Author" content="">
  7   <meta name="Keywords" content="">
  8   <meta name="Description" content="">
  9   <title>原生JS实现ajax和JSONP请求</title>
 10   <style type="text/css">
 11     input[type=‘button‘] {
 12         margin:20px;
 13     }
 14   </style>
 15  </head>
 16  <body>
 17   <button>点击验证AJAX</button>
 18   <input type="button" value="点击验证JSONP" onclick="">
 19   <div id="div1" class="">
 20     
 21   </div>
 22  </body>
 23  <script type="text/javascript">
 24  <!--
 25     //原生JS方法封装AJAX请求和JSONP请求
 26 
 27     window.Ajax = (object) => {
 28         object = object || {};
 29         object.data = object.data || {};
 30         //判断请求类型为AJAX或者JSONP
 31         let json = object.jsonp ? Jsonp(object) : ajax(object);
 32 
 33         //设置ajax方法
 34         function ajax(object) {
 35            // 1.设置请求方式:如果没有制定则默认为GET
 36            object.type = (object.type || GET).toUpperCase();
 37            // 2.设置data数据的格式化
 38            object.data = formateObject(object.data);
 39            // 3.实例化XMLHttpRequest对象  
 40            var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject(Microsoft.XMLHTTP);
 41            // 4.监听事件,只要readyState改变,就会调用readystatechange事件
 42            xhr.onreadystatechange = function(){
 43                // readyState属性表示请求/响应过程的当前活动阶段,4为完成,已经接收到全部响应数据
 44                if(xhr.readyState == 4) {
 45                    let status = xhr.status;
 46                    // status : HTTP响应的状态码,2开头表示成功
 47                    if(status >=200 && status < 300){
 48                        let response = ‘‘;
 49                        // 判断接受数据的内容类型 
 50                        let type = xhr.getResponseHeader(Content-type);  
 51                        if(type.indexOf(xml) !== -1 && xhr.responseXML) {  
 52                           response = xhr.responseXML; //Document对象响应  
 53                          } else if(type === application/json) {  
 54                           response = JSON.parse(xhr.responseText); //JSON响应  
 55                          } else {  
 56                           response = xhr.responseText; //字符串响应  
 57                         }; 
 58                         // 成功回调函数 
 59                         object.success && object.success(response);  
 60                    }else {
 61                         object.error && object.error(response);  
 62                    }
 63                }
 64            }
 65 
 66            
 67            // 5.连接和传输数据
 68            if(object.type == GET) {
 69                // 三个参数:请求方式、请求地址(get方式时,传输数据是加在地址后的)、是否异步请求(同步请求的情况极少);
 70                xhr.open(object.type, object.url + ? + object.data, true);  
 71                xhr.send(null);  
 72             } else {  
 73                xhr.open(object.type, object.url, true);  
 74                //必须,设置提交时的内容类型  
 75                xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded; charset=UTF-8); 
 76                // 传输数据 
 77                xhr.send(object.data); 
 78             }
 79         }
 80 
 81         //设置Jsonp方法
 82         function Jsonp(object) {
 83           // 创建script标签并加入到页面中
 84           let callbackName = object.jsonp,
 85               head = document.getElementsByTagName(head)[0];
 86           // 设置传递给后台的回调参数名  
 87           object.data[callback] = callbackName;  
 88           let data = formateObject(object.data),
 89               script = document.createElement(script);  
 90           head.appendChild(script);  
 91           // 创建JSONP的回调函数
 92           //创建jsonp回调函数  
 93           window[callbackName] = function(json) {  
 94               head.removeChild(script);  
 95               clearTimeout(script.timer);  
 96               window[callbackName] = null;  
 97               object.success && object.success(json);  
 98           };  
 99           // 发送请求
100           script.src = object.url + ? + data;  
101           //为了得知此次请求是否成功,设置超时处理  
102           if(object.time) {  
103            script.timer = setTimeout(function() {  
104             window[callbackName] = null;  
105             head.removeChild(script);  
106             object.error && object.error({  
107              message: 请求超时 
108             });  
109            }, time);  
110           }  
111 
112         }
113         
114 
115         //data的格式化方法
116         function formateObject(data){
117            if(data){
118                let arr = [];
119                for(let name in data){
120                    //encodeURIComponent() :用于对 URI 中的某一部分进行编码
121                    arr.push(encodeURIComponent(name) + = + encodeURIComponent(data[name]));
122                }
123 
124                //为了防止缓存,在后面添加一个随机数
125                arr.push(randomV= + randomNumber());
126                return arr.join(&);
127            }else {
128                console.error(无法格式化请求数据)
129            }
130         }
131 
132         //生成随机数的方法
133         function randomNumber(){
134             return Math.floor(Math.random()*10000+404);
135         }
136 
137     };
138 
139 
140     const button = document.querySelector(input[type="button"]);
141     const btn = document.querySelector(button);
142 
143     const successFun = (res) => {
144         console.log(res);
145         let div1= document.querySelector("#div1");
146         div1.innerHTML = res.name + res.gender;
147     };
148     const obj = {
149         url : jsonp.php,
150         type : GET,
151         jsonp : callback,
152         data : ‘‘,
153         success: successFun,
154         error: function(){
155         }
156     };
157 
158     const obj1 = {
159         url : test.json,
160         type : GET,
161         data : ‘‘,
162         success: successFun,
163         error: function(){
164         }
165     };
166 
167 
168     button.addEventListener(click, () => Ajax(obj));
169     btn.addEventListener(click,() => Ajax(obj1));
170 
171     
172  //-->
173  </script>
174 </html>


测试效果:

技术分享图片

 

 

验证JSONP:

技术分享图片

 

用原生JS实现AJAX和JSONP

标签:lin   upper   需要   request对象   tor   res   type   input   error:   

原文地址:https://www.cnblogs.com/liquanjiang/p/8992382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!