分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

用原生JS实现AJAX和JSONP

发布时间:2023-09-06 01:52责任编辑:白小东关键词:JSONP

前端开发在需要与后端进行数据交互时,为了方便快捷,都会选择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.设置请求方式:如果没有制定则默认为GET10 ???????????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

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

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved