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

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

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

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

  const Ajax = (object) => {
object = object || {};
object.data = object.data || {};
//判断请求类型为AJAX或者JSONP
let json = object.jsonp ? Jsonp(object) : ajax(object); //设置ajax方法
function ajax(object) {
// 1.设置请求方式:如果没有制定则默认为GET
object.type = (object.type || 'GET').toUpperCase();
// 2.设置data数据的格式化
object.data = formateObject(object.data);
// 3.实例化XMLHttpRequest对象
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
// 4.监听事件,只要readyState改变,就会调用readystatechange事件
xhr.onreadystatechange = function(){
// readyState属性表示请求/响应过程的当前活动阶段,4为完成,已经接收到全部响应数据
if(xhr.readyState == 4) {
let status = xhr.status;
// status : HTTP响应的状态码,2开头表示成功
if(status >=200 && status < 300){
let response = '';
// 判断接受数据的内容类型
let 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; //字符串响应
};
// 成功回调函数
object.success && object.success(response);
}else {
object.error && object.error(response);
}
}
} // 5.连接和传输数据
if(object.type == 'GET') {
// 三个参数:请求方式、请求地址(get方式时,传输数据是加在地址后的)、是否异步请求(同步请求的情况极少);
xhr.open(object.type, object.url + '?' + object.data, true);
xhr.send(null);
} else {
xhr.open(object.type, object.url, true);
//必须,设置提交时的内容类型
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
// 传输数据
xhr.send(object.data);
}
} //data的格式化方法
function formateObject(data){
if(data){
let arr = [];
for(let name in data){
//encodeURIComponent() :用于对 URI 中的某一部分进行编码
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
} //为了防止缓存,在后面添加一个随机数
arr.push('randomV=' + randomNumber());
return arr.join('&');
}else {
console.error('无法格式化请求数据')
}
} //生成随机数的方法
function randomNumber(){
return Math.floor(Math.random()*10000+404);
} };

同理,我们也可以实现一个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内容

 {
"name" : "111",
"gender" : "222"
}

jsonp.php内容:

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

index.html内容

 <!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>原生JS实现ajax和JSONP请求</title>
<style type="text/css">
input[type='button'] {
margin:20px;
}
</style>
</head>
<body>
<button>点击验证AJAX</button>
<input type="button" value="点击验证JSONP" onclick="">
<div id="div1" class=""> </div>
</body>
<script type="text/javascript">
<!--
//原生JS方法封装AJAX请求和JSONP请求 window.Ajax = (object) => {
object = object || {};
object.data = object.data || {};
//判断请求类型为AJAX或者JSONP
let json = object.jsonp ? Jsonp(object) : ajax(object); //设置ajax方法
function ajax(object) {
// 1.设置请求方式:如果没有制定则默认为GET
object.type = (object.type || 'GET').toUpperCase();
// 2.设置data数据的格式化
object.data = formateObject(object.data);
// 3.实例化XMLHttpRequest对象
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
// 4.监听事件,只要readyState改变,就会调用readystatechange事件
xhr.onreadystatechange = function(){
// readyState属性表示请求/响应过程的当前活动阶段,4为完成,已经接收到全部响应数据
if(xhr.readyState == 4) {
let status = xhr.status;
// status : HTTP响应的状态码,2开头表示成功
if(status >=200 && status < 300){
let response = '';
// 判断接受数据的内容类型
let 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; //字符串响应
};
// 成功回调函数
object.success && object.success(response);
}else {
object.error && object.error(response);
}
}
} // 5.连接和传输数据
if(object.type == 'GET') {
// 三个参数:请求方式、请求地址(get方式时,传输数据是加在地址后的)、是否异步请求(同步请求的情况极少);
xhr.open(object.type, object.url + '?' + object.data, true);
xhr.send(null);
} else {
xhr.open(object.type, object.url, true);
//必须,设置提交时的内容类型
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
// 传输数据
xhr.send(object.data);
}
} //设置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);
} } //data的格式化方法
function formateObject(data){
if(data){
let arr = [];
for(let name in data){
//encodeURIComponent() :用于对 URI 中的某一部分进行编码
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
} //为了防止缓存,在后面添加一个随机数
arr.push('randomV=' + randomNumber());
return arr.join('&');
}else {
console.error('无法格式化请求数据')
}
} //生成随机数的方法
function randomNumber(){
return Math.floor(Math.random()*10000+404);
} }; const button = document.querySelector('input[type="button"]');
const btn = document.querySelector('button'); const successFun = (res) => {
console.log(res);
let div1= document.querySelector("#div1");
div1.innerHTML = res.name + res.gender;
};
const obj = {
url : 'jsonp.php',
type : 'GET',
jsonp : 'callback',
data : '',
success: successFun,
error: function(){
}
}; const obj1 = {
url : 'test.json',
type : 'GET',
data : '',
success: successFun,
error: function(){
}
}; button.addEventListener('click', () => Ajax(obj));
btn.addEventListener('click',() => Ajax(obj1)); //-->
</script>
</html>

测试效果:

验证JSONP:

用原生JS实现AJAX和JSONP的更多相关文章

  1. 用原生js实现ajax、jsonp

    转载: http://www.cnblogs.com/yangheng/p/6065910.html 一.原生js实现ajax $.ajax({ url: '', type: 'post', data ...

  2. 原生JS实现AJAX、JSONP及DOM加载完成事件,并提供对应方法

    JS原生AJAX ajax:一种请求数据的方式,不需要刷新整个页面: ajax的技术核心是 XMLHttpRequest 对象: ajax 请求过程:创建 XMLHttpRequest 对象.连接服务 ...

  3. 原生JS实现AJAX、JSONP及DOM加载完成事件

    一.JS原生Ajax ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务 ...

  4. 原生JS实现Ajax及Ajax的跨域请求

      前  言          如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...

  5. 原生js实现Ajax

    一般来说,大家可能都会习惯用JQuery提供的Ajax方法,但是用原生的js怎么去实现Ajax方法呢? JQuery提供的Ajax方法: $.ajax({ url: , type: '', dataT ...

  6. 使用原生js写ajax

    // 使用原生js 封装ajax // 兼容xhr对象 function createXHR(){ if(typeof XMLHttpRequest != "undefined") ...

  7. 表单验证--通过原生js模仿ajax的异步交互

    今天给大家带来个福利,我也是刚刚学习的很实用的一个东西,通过原生js模仿ajax的异步交互. 我的博客只是给那些新手看的大神勿喷,写的不好可留言,请指出. 因为当初自己学的时候一个问题不会找人问,知道 ...

  8. 原生JS的Ajax技术

    1.同步和异步 同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待  卡死状态 异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随意做其他事情,不会被卡 ...

  9. 原生js中用Ajax进行get传参

    原生js中用Ajax进行get传参 案例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...

随机推荐

  1. [POI2007]洪水pow 题解

    [POI2007]洪水pow 时间限制: 5 Sec  内存限制: 128 MB 题目描述 AKD市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD市全被水淹没了.Blue Mary,AKD ...

  2. MFC在一个工程中启动其他工程的exe文件

    说明:有的时候把两个工程合并,但是偷懒不想在工程中添加代码,所以想到了这个办法,仅限偷懒哈哈哈哈 方法:新建一个主程序,在主程序的界面中添加按钮,在按钮的程序代码中添加以下语句: void CMain ...

  3. duilib加消息

    一.加消息 1. public INotifyUI, 2. void Notify(TNotifyUI& msg); 3. Notify实现 4. m_pManager->AddNoti ...

  4. sklearn使用技巧

    sklearn使用技巧 sklearn上面对自己api的解释已经做的淋漓尽致,但对于只需要短时间入手的同学来说,还是比较复杂的,下面将会列举sklearn的使用技巧. 预处理 主要在sklearn.p ...

  5. Javascript中style,currentStyle和getComputedStyle的区别以及获取css操作方法

    style: 只能获取行内style. 调用:obj.style.属性; 兼容:都兼容 currentStyle: 可以获取该obj所有style,但只可读. 调用:obj.currentStyle[ ...

  6. [leetcode]914. X of a Kind in a Deck of Cards (easy)

    原题 题目原意可转换为 两组有大于等于2的公因数 /** * @param {number[]} deck * @return {boolean} */ var hasGroupsSizeX = fu ...

  7. 【译】WebAPI,Autofac,以及生命周期作用域

    说明 原文地址:http://decompile.it/blog/2014/03/13/webapi-autofac-lifetime-scopes/ 介绍 这是一篇关于AutoFac的生命周期作用域 ...

  8. (原创)将Datatable数据按照Excel模板格式导出

    最近遇到一个问题,就是导出数据的时候需要自定义的表头,如图 如果自己用代码写表头的话,可能会有点复杂,而且代码量很多,所以我就想了一个办法,直接在Excel里面把表头定义好,然后把数据写入Excel模 ...

  9. React躬行记(11)——Redux基础

    Redux是一个可预测的状态容器,不但融合了函数式编程思想,还严格遵循了单向数据流的理念.Redux继承了Flux的架构思想,并在此基础上进行了精简.优化和扩展,力求用最少的API完成最主要的功能,它 ...

  10. 彻底搞懂Python切片操作

        在利用Python解决各种实际问题的过程中,经常会遇到从某个对象中抽取部分值的情况,切片操作正是专门用于完成这一操作的有力武器.理论上而言,只要条件表达式得当,可以通过单次或多次切片操作实现任 ...