JavaScript:原生模拟$.ajax以及jsonp
现实项目中,常常会用到请求,但是在考虑低版本的浏览器时,promise相关的axios,fetch这类第三方库的支持率就不那么好了,再考虑到最大的一个问题,跨域,更是让人头痛,虽然也有fetch-jsonp的方案,但是引入过多的库反而让项目变得复杂,后期插件版本升级等就比较繁琐。最常用的也是曾经红极一时的,那一定是jQuery或者zepto的$.ajax方案了,完美兼容多平台浏览器及低版本,支持jsonp跨域等,但是在现在大多数项目已不再用jQuery或zepto来实现开发,大多数用的是React,vue等前端库,所以如果仅仅为了一个ajax就引入一个库,未免有点浪费,所以,最好还是自己封装一个ajax函数,来模仿jQuery的$.ajax。
先看一下实现后的使用案例:
第一种,普通请求:
ajax({
url: 'test.php', // 请求地址
type: 'POST', // 请求类型,默认"GET",还可以是"POST"
data: {'b': '异步请求'}, // 传输数据
success: function(res){ // 请求成功的回调函数
console.log(JSON.parse(res));
},
error: function(error) {} // 请求失败的回调函数
});
第二种,跨域请求:
ajax({
url: 'test', // 请求地址
jsonp: 'jsonpCallback', // 采用jsonp请求,且回调函数名为"jsonpCallbak",可以设置为合法的字符串
data: {'b': '异步请求'}, // 传输数据
success:function(res){ // 请求成功的回调函数
console.log(res);
},
error: function(error) {} // 请求失败的回调函数
});
可以看出,都是用了ajax()这个方法,用法就跟jQuery的$.ajax一样,那如何实现?
不多说,直接上代码:
function ajax(params) {
params = params || {};
params.data = params.data || {};
var json = params.jsonp ? jsonp(params) : json(params);
}
function json(params) {
params.type = (params.type || 'GET').toUpperCase();
params.data = formatParams(params.data);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
var type = xhr.getResponseHeader('Content-Type');
if (type.indexOf('xml') !== -1 && xhr.responseXML) {
// document 对象响应
var response = xhr.responseXML;
} else if (type == 'application/json') {
// JSON响应
var response = JSON.parse(xhr.responseText);
} else {
// 字符串响应
var response = xhr.responseText;
}
params.success && params.success(response);
} else {
params.error && params.error(status);
}
}
}
if (params.type == 'GET') {
xhr.open('GET', 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 jsonp(params){
var callbackName = params.jsonp;
var head = document.getElementsByTagName('head')[0];
params.data['callback'] = callbackName;
params.data = formatParams(params.data);
var script = document.createElement('script');
head.appendChild(script);
window[callbackName] = function(json){
head.removeChild(script);
window[callbackName] = null;
clearTimeout(script.timer);
params.success && params.success(json)
}
script.url = params.url + '?' + params.data;
// 设置超时限制
if (params.time) {
script.timer = setTimeout(function(){
window[callbackName] = null;
clearTimeout(script.timer);
head.removeChild(script);
params.error && params.error({
message: '超时'
});
}, params.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)
}
这里有几个要注意的点:
1,参数为空的处理;
2,如果是非jsonp,在监听onreadyStateChange事件时,针对成功请求的结果,还要分情况处理返回值,根据Content-Type后面的值来讨论;
3,发送请求的时候,如果是非GET请求,需要设置请求头;
4,如果是jsonp,在调用回调的时候,一定要做内存清理、定时器清理等,保证性能;
5,数据格式化的时候,要用encodeURIComponent来处理,除了中间的=号,键和值都要处理,然后在末尾要添加随机数,防止缓存;
end
JavaScript:原生模拟$.ajax以及jsonp的更多相关文章
- JavaScript原生封装ajax请求和Jquery中的ajax请求
前言:ajax的神奇之处在于JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果.Ajax 在浏览器与 Web 服务器之间使用异步 ...
- 原生 JavaScript 实现 AJAX、JSONP
相信大多数前端开发者在需要与后端进行数据交互时,为了方便快捷,都会选择JQuery中封装的AJAX方法,但是有些时候,我们只需要JQuery的AJAX请求方法,而其他的功能用到的很少,这显然是没必要的 ...
- 原生JavaScript实现AJAX、JSONP
相信大多数前端开发者在需要与后端进行数据交互时,为了方便快捷,都会选择JQuery中封装的AJAX方法,但是有些时候,我们只需要JQuery的AJAX请求方法,而其他的功能用到的很少,这显然是没必要的 ...
- 原生javascript封装ajax和jsonp
在我们请求数据时,完成页面跨域,利用原生JS封装的ajax和jsonp: <!DOCTYPE html> <html lang="en"> <head ...
- 用原生JS实现AJAX和JSONP
前端开发在需要与后端进行数据交互时,为了方便快捷,都会选择JQuery中封装的AJAX方法,但是有些时候,我们只需要JQuery的AJAX请求方法,而其他的功能用到的很少,这显然是没必要的.其实,原生 ...
- 原生ajax和jsonp
封装方法: function ajax(options) { options = options || {}; options.type = (options.type || "GET&qu ...
- 框架----Django之Ajax全套实例(原生AJAX,jQuery Ajax,“伪”AJAX,JSONP,CORS)
一.原生AJAX,jQuery Ajax,“伪”AJAX,JSONP 1. 浏览器访问 http://127.0.0.1:8000/index/ http://127.0.0.1:8000/fake_ ...
- 从 AJAX 到 JSONP的基础学习
目录索引: 一.AJAX的概念二.POST && GET三.原生实现AJAX简单示例 3.1 实现代码 3.2 重点说明四.框架隐藏域 4.1 基本概念 4.2 后台写入脚本 4.3 ...
- ajax 和jsonp 不是一码事
由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...
随机推荐
- JAVA 每周一 每周日 时间
Calendar cal = Calendar.getInstance(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd&q ...
- CSV文件乱码展示(编码格式问题)
最开始mac上打开CSV文件乱码,是这样的:CSV文件编码格式为UTF-8 解决办法一:将excel文件同样的转换编码格式为utf-8,具体操作如下: 去掉tab,勾选comma 最后,将文件另存为u ...
- tensorflow-yolo3系列配置文章汇总
yolo 网络讲解 https://blog.csdn.net/m0_37192554/article/details/81092514 https://blog.csdn.net/guleileo/ ...
- matlab-非线性拟合函数lsqcurvefit的使用和初值选取
所解决问题: 我们知道我们的表达式是y=A+B*exp(-x.^2)-C./log(x), 而且现在我们手里面有x与y对应的一大把数据. 我们需要根据x, y的值找出最佳的A.B.C值.则我们现在借助 ...
- Java中通过Class的反射来获取方法
本文转自:http://z3sm2012.iteye.com/blog/1933227 今天在程序中用到java反射机制时,遇到的问题记录一下:我当时遇到的问题是,我用反射getMethod()调用类 ...
- sass的基本使用
使用sass的前提是安装Ruby,如果是Mac系统,那么免去安装,Windows系统需要自行安装https://www.sass.hk/install/.当安装好以后,直接执行安装sass命令:gem ...
- Controller层aop
利用@Around通知修改Controller的返回值 自定义一个注解@OperationBtn 在切入点Controller上加上自定义注解 接下来就是重点了,AspectJ写切面类,对该Contr ...
- SQL(ORACLE)
查询数据库编码: select * from sys.nls_database_parameters;select * from sys.nls_session_parameters; replace ...
- 29.Hibernate-二级缓存和session管理.md
目录 1.概念 1.1一级缓存: 1.2二级缓存: 2.使用方法 3.策略 3.1缓存策略 3.2集合缓存 3.3查询缓存 5. Seesion管理 1.概念 Hibernate提供的缓存 有一级缓存 ...
- 修改CKplayer.js 源码解决移动端浏览器全屏不能限制快进的问题
原文地址:https://www.cnblogs.com/jying/p/9642445.html,转载请说明出处. 最近项目需要播放视频且限制未观看部分的快进功能,找了两款js插件ckplayer和 ...