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通讯 ...
随机推荐
- 减肥标准BMI指数
原文: https://baike.baidu.com/item/BMI%E6%8C%87%E6%95%B0/4477882?fromtitle=%E4%BD%93%E9%87%8D%E6%8C%87 ...
- gitea 源码阅读笔记 002 生成无依赖单文件可执行包
gitea bindata static gitea 可以通过 make generate 生成一个单文件可执行程序, 该文件不需要任何其它依赖,直接可以单独执行. 对于用户的安装.升级和生成dock ...
- vm虚拟机 模板机进行克隆导致centos 7.2 无法加载网卡
问题描述:vm虚拟机 模板机进行克隆导致centos 7.2 无法加载网卡. 1.ifconfig 查看网卡状态 lo: flags=<UP,LOOPBACK,RUNNING> mtu i ...
- 谷歌浏览器内核Cef js代码整理(三) 字符串处理
*字符串截取方法*/ var s="abc_def[ghi]jk[i]"; var temp;function CopyFromStr(str_source,str_key, bl ...
- Cookie的存活时间
1. 默认情况下,cookie数据保存到内存里,当浏览器关闭后,Cookie数据被销毁 2. 持久化存储: setMaxAge(int seconds) 1. 正数:将Cookie数据写到硬盘的文件中 ...
- JS数据类型的判断
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefine ...
- python中 函数名加括号与不加括号
加括号是返回函数的结果,不加括号相当于函数的调用.
- Redis-Sentinel 数据源配置
1.redis配置文件 : redis.properties # Redis settings #sentinel_node_1 redis.sentinel1.host=192.168.0.1 re ...
- Android应用开发中,第三方集成新浪微博(sinaWeiboSDK)的过程记录
作为一个android开发人员,不可避免的要学会使用和集成第三方API的能力 而新浪微博作为现在最主要的新闻速递媒体,使用十分普遍,并且提供了较为详细的API接入方法,故此选择集成sinaWeibiS ...
- VSCode搭建Java开发运行环境
用了一段时间VSCode,觉得还可以,想用VSCode整合不同的开发语言,于是研究了一下利用VSCode搭建Java环境.开发Java程序.网上这方面的帖子有不少,但每人的经历不同,把自己的经历记下来 ...