前端开发在需要与后端进行数据交互时,为了方便快捷,都会选择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. Java底层技术系列文章-总揽

    对于工作中经常用到的东西,还是多看看实现原理,这样用着才能放心. 源码思想学习计划: 1.java基础库  HashCode深入理解 java线程框架窥探 2.集合类     java枚举类使用 递归 ...

  2. 程序员要搞明白CDN,这篇应该够了

    最近在了解边缘计算,发现我们经常听说的CDN也是边缘计算里的一部分.那么说到CDN,好像只知道它中文叫做内容分发网络.那么具体CDN的原理是什么?能够为用户在浏览网站时带来什么好处呢?解决这两个问题是 ...

  3. Learning the Depths of Moving People by Watching Frozen

    基于双目的传统算法 对静止的物体, 在不同的 viewpoints 同一时刻进行拍摄, 根据拍摄到的结果, 使用三角测量算法计算出平面 2D 图像在 3D 图像中的坐标 单目 Ground Truth ...

  4. kali linux 常用文件与指令路径

    重启网络 : /etc/init.d/networking restart 语言设置文件 : /etc/default/locale apt 安装deb保存目录 : /var/cache/apt/ar ...

  5. Java中的Enumeration、Iterable和Iterator接口详解

    前言 在看各类Java书籍或者博文的时候,总是会遇到Enumeration.Iterable和Iterator这三个接口,如果对这几个接口不是很明白的话,总会让自己看着看着就迷惑了,正好这周末,抽空把 ...

  6. python中的字典,if_while使用

    1.定义两个字典用于表述你的个人信息 第一个字典存放你的这些信息:姓名.性别.年龄.身高第二个字典存放你的其他信息:性格.爱好.座右铭将两个字典合并为第三个字典之后,打印出来 觉得自己很年轻的,可以去 ...

  7. [leetcode] 392. Is Subsequence (Medium)

    原题 判断子序列 /** * @param {string} s * @param {string} t * @return {boolean} */ var isSubsequence = func ...

  8. 小白开学Asp.Net Core《二》(补)

    小白开学Asp.Net Core<二>(补) ——数据仓储层(Repositroy).服务层(Service) -------------------------------------- ...

  9. 前端响应式痛点解决之box-sizing

    前置 在 CSS 盒子模型的默认定义里,你对一个元素所设置的 width 与 height 只会应用到这个元素的内容区.如果这个元素有任何的 border 或 padding ,绘制到屏幕上时的盒子宽 ...

  10. 【原创】用事实说话,Firefox 的性能是 Chrome 的 2 倍,Edge 的 4 倍,IE11 的 6 倍!

    前言 每个浏览器新版本发布,都号称性能有显著提升,并且市面有各种测试工具,测试结果也是大相径庭,比如下面这篇文章: https://www.oschina.net/news/97924/browser ...