js异步请求php数据,原生JS发送异步数据请求实例详解

这篇文章主要为大家详细介绍了原生JS发送异步数据请求的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在做项目的时候,有时候需要用到异步数据请求,但是如果这个时候没有框架的依赖,就需要用到原生JS进行异步数据请求。这时候无非有两种请求方式,一种是AJAX,另一个是JSONP。通过原生JS对异步请求进行简单的封装。

AJAX

AJAX是一种数据请求方式,不需要刷新整个页面就能够更新局部页面的数据。AJAX的技术核心是XMLHttpRequest对象,主要请求过程如下:创建XMLHttpRequest对象(new)

连接服务器(open)

发送请求(send)

接收响应数据(onreadystatechange)

不说话直接贴代码

/**

* 通过JSON的方式请求

* @param {[type]} params [description]

* @return {[type]} [description]

*/

ajaxJSON(params) {

params.type = (params.type || 'GET').toUpperCase();

params.data = params.data || {};

var formatedParams = this.formateParams(params.data, params.cache);

var xhr;

//创建XMLHttpRequest对象

if (window.XMLHttpRequest) {

//非IE6

xhr = new XMLHttpRequest();

} else {

xhr = new ActiveXObject('Microsoft.XMLHTTP');

}

//异步状态发生改变,接收响应数据

xhr.onreadystatechange = function() {

if (xhr.readyState == 4 && xhr.status == 200) {

if (!!params.success) {

if (typeof xhr.responseText == 'string') {

params.success(JSON.parse(xhr.responseText));

} else {

params.success(xhr.responseText);

}

}

} else {

params.error && params.error(status);

}

}

if (params.type == 'GET') {

//连接服务器

xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);

//发送请求

xhr.send();

} else {

//连接服务器

xhr.open('POST', params.url, true);

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

//发送请求

xhr.send(formatedParams);

}

},

/**

* 格式化数据

* @param {Obj} data 需要格式化的数据

* @param {Boolean} isCache 是否加入随机参数

* @return {String} 返回的字符串

*/

formateParams: function(data, isCache) {

var arr = [];

for (var name in data) {

arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));

}

if (isCache) {

arr.push('v=' + (new Date()).getTime());

}

return arr.join('&');

}

IE7及其以上版本中支持原生的 XHR 对象,因此可以直接用:var oAjax = new XMLHttpRequest();。IE6及其之前的版本中,XHR对象是通过MSXML库中的一个ActiveXObject对象实现的。

通过xhr的open函数来连接服务器,主要接收三个参数:请求方式、请求地址和是否异步请求(一般都是异步请求)。请求方式有两种,GET和POST,GET是通过URL将数据提交到服务器的,POST则是通过将数据作为send方法的参数发送到服务器。

给xhr绑定状态改变函数onreadystatechange,主要用来检测xhr的readyState的变化,当异步发送成功后,readyState的数值会由0变成4,同时触发onreadystatechange事件。readyState的属性及对应状态如下:

0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)

1 (初始化) 对象已建立,尚未调用send方法

2 (发送数据) send方法已调用,但是当前的状态及http头未知

3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误

4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据

在readystatechange事件中,先判断响应是否接收完成,然后判断服务器是否成功处理请求,xhr.status 是状态码,状态码以2开头的都是成功,304表示从缓存中获取,上面的代码在每次请求的时候都加入了随机数,所以不会从缓存中取值,故该状态不需判断。

JSONP

如果还是用上面的XMLHttpRequest对象来发送需要跨域的请求,虽然调用了send函数,但是xhr的状态一直都是0,也不会触发onreadystatechange事件,这个时候就要用到JSONP的请求方式了。

JSONP(JSON with Padding) 是一种跨域请求方式。主要原理是利用了script标签可以跨域请求的特点,由其src属性发送请求到服务器,服务器返回js代码,网页端接受响应,然后就直接执行了,这和通过script标签引用外部文件的原理是一样的。

JSONP由两部分组成:回调函数和数据,回调函数一般是由网页端控制,作为参数发往服务器端,服务器端把该函数和数据拼成字符串返回。

比如网页端创建一个script标签,并给其src赋值为http://www.test.com/json/?callback=process, 此时网页端就发起一个请求。服务端将要返回的数据拼作为函数的参数传入,服务端返回的数据格式类似”process({‘name:'xieyufei'})”,网页端接收到了响应值,因为请求者是 script,所以相当于直接调用process方法,并且传入了一个参数。

不说话直接贴代码。

/**

* 通过JSONP的方式请求

* @param {[type]} params [description]

* @return {[type]} [description]

*/

ajaxJSONP(params) {

params.data = params.data || {};

params.jsonp = params.jsonp || 'callback';

// 设置传递给后台的回调参数名和参数值

var callbackName = 'jsonp_' + (new Date()).getTime();

params.data[params.jsonp] = callbackName;

var formatedParams = this.formateParams(params.data, params.cache);

//创建script标签并插入到页面中

var head = document.getElementsByTagName('head')[0];

var script = document.createElement('script');

head.appendChild(script);

//创建jsonp回调函数

window[callbackName] = function(json) {

head.removeChild(script);

clearTimeout(script.timer);

window[callbackName] = null;

params.success && params.success(json);

};

//发送请求

script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url);

//为了得知此次请求是否成功,设置超时处理

if (params.time) {

script.timer = setTimeout(function() {

window[callbackName] = null;

head.removeChild(script);

params.error && params.error({

message: '超时'

});

}, params.time);

}

}

给script标签设置src属性时浏览器就会去发送请求,但是只能发送一次请求,导致script标签不能复用,因此每次操作完都需要把script标签移除。在浏览器发送请求之前给全局绑定一个回调函数,当数据请求成功时就会调用这个回调函数。

总结

将两种发送异步数据的方式整合起来,根据dataType来进行判断选用哪种方式。贴上完整的代码

var xyfAjax = {

ajax: function(params) {

params = params || {};

params.cache = params.cache || false;

if (!params.url) {

throw new Error('参数不合法');

}

params.dataType = (params.dataType || 'json').toLowerCase();

if (params.dataType == 'jsonp') {

this.ajaxJSONP(params);

} else if (params.dataType == 'json') {

this.ajaxJSON(params);

}

},

/**

* 通过JSONP的方式请求

* @param {[type]} params [description]

* @return {[type]} [description]

*/

ajaxJSONP(params) {

params.data = params.data || {};

params.jsonp = params.jsonp || 'callback';

// 设置传递给后台的回调参数名和参数值

var callbackName = 'jsonp_' + (new Date()).getTime();

params.data[params.jsonp] = callbackName;

var formatedParams = this.formateParams(params.data, params.cache);

//创建script标签并插入到页面中

var head = document.getElementsByTagName('head')[0];

var script = document.createElement('script');

head.appendChild(script);

//创建jsonp回调函数

window[callbackName] = function(json) {

head.removeChild(script);

clearTimeout(script.timer);

window[callbackName] = null;

params.success && params.success(json);

};

//发送请求

script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url);

//为了得知此次请求是否成功,设置超时处理

if (params.time) {

script.timer = setTimeout(function() {

window[callbackName] = null;

head.removeChild(script);

params.error && params.error({

message: '超时'

});

}, params.time);

}

},

/**

* 通过JSON的方式请求

* @param {[type]} params [description]

* @return {[type]} [description]

*/

ajaxJSON(params) {

params.type = (params.type || 'GET').toUpperCase();

params.data = params.data || {};

var formatedParams = this.formateParams(params.data, params.cache);

var xhr;

//创建XMLHttpRequest对象

if (window.XMLHttpRequest) {

//非IE6

xhr = new XMLHttpRequest();

} else {

xhr = new ActiveXObject('Microsoft.XMLHTTP');

}

//异步状态发生改变,接收响应数据

xhr.onreadystatechange = function() {

if (xhr.readyState == 4 && xhr.status == 200) {

if (!!params.success) {

if (typeof xhr.responseText == 'string') {

params.success(JSON.parse(xhr.responseText));

} else {

params.success(xhr.responseText);

}

}

} else {

params.error && params.error(status);

}

}

if (params.type == 'GET') {

//连接服务器

xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);

//发送请求

xhr.send(null);

} else {

//连接服务器

xhr.open('POST', params.url, true);

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

//发送请求

xhr.send(formatedParams);

}

},

/**

* 格式化数据

* @param {Obj} data 需要格式化的数据

* @param {Boolean} isCache 是否加入随机参数

* @return {String} 返回的字符串

*/

formateParams: function(data, isCache) {

var arr = [];

for (var name in data) {

arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));

}

if (isCache) {

arr.push('v=' + (new Date()).getTime());

}

return arr.join('&');

}

}

xyfAjax.ajax({

url:'http://www.xieyufei.com',

type:'get', //or post

dataType:'json', //or jsonp

data:{

name:'xyf'

},

success: function(data){

console.log(data)

}

})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555822.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis-Plus——增删查改

开发环境 IDEA JDK:1.8 Spring Boot:2.6.2 Maven:3.3.9 MySQL:8.0.23 数据库准备 CREATE DATABASE mybatis_plus_db;DROP TABLE IF EXISTS person; CREATE TABLE person(id BIGINT(20) NOT NULL COMMENT 主键ID, name VARCHAR(30) NULL DEFAULT NULL COMMENT 姓…

让程序员最爽的ThreadLocal使用姿势

一、常见场景 ​ 1、ThreadLocal作为线程上下文副本,那么一种最常见的使用方式就是用来方法隐式传参,通过提供的set()和get()两个public方法来实现在不同的方法中的参数传递。对于编程规范来说,方法定义的时候是对参数个数是有限制的&#x…

php 堆和栈示例,php中堆和栈的使用

这篇文章介绍的内容是关于php中堆和栈的使用,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下一、关于堆和栈的概念及区别这里参考上篇博客: 浅谈堆和栈的区别通过这篇文章,我们可以知道广义的堆和栈到底…

一场事故告诉你zookeeper和nacos谁更适合做注册中心

前言 ​ 在分布式系统中,注册中心充当着重要角色,是服务发现、客户端负载均衡中不可缺少的一员。注册中心除了能够实现基本的功能外,他的稳定性、可用性和健壮性对整个分布式系统的流畅运行影响重大。dubbo作为国内一款主流的分布式系统&…

mysql 排他,mysql 共享锁 排他锁 防插入锁

试验1事务1:#!/usr/bin/pythonimport timeimport MySQLdb;conn MySQLdb.connect(host"localhost",port3306,user"root",passwd"asdf",db"test",unix_socket"/data/mysql_3306/mysql.sock")cursor conn.cursor(…

MySQL操作之JSON数据类型操作详解

MySQL操作之JSON数据类型操作详解 这篇文章主要介绍了MySQL操作之JSON数据类型操作详解,内容较为详细,具有收藏价值,需要的朋友可以参考。 概述 mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了my…

Mysql执行计划含义,mysql执行计划介绍

烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长。如何写好sql,学会看执行计划至关重要。下面我简单讲讲mysql的执行计划,只列出了一些常见的情况,希望对大家有所帮助。测试表结构&…

Http GET 请求参数中文乱码

Http GET 请求参数中文乱码 两种解决方式 第1种:代码里转换 String name request.getParamter("name"); String nameUtf8 new String(name.getBytes("ISO8859-1"), "UTF-8");第2种:修改Tomcat配置 TOMCAT_HOME/conf…

matlab randomsample,randperm和randsample函数用法对比

构建替代数据的时候,一种常见的思路是打乱原数据的排列次序,通过随机置换原数据的排列次序从而产生和原数据系列统计特征(如均值、方差、分布)一致的随机数据。具体到Matlab中,此思路的实现会涉及到两个命令:randperm和randsample…

SpringBoot的编码问题

第一种方式:直接在配置文件中设置浏览器的解析编码的格式 #设置字符编码 #开启springboot的http字符编码的支持 spring.http.encoding.enabledtrue #强制使用指定字符编码 spring.http.encoding.forcetrue #指定使用的字符编码 spring.http.encoding.charsetUTF-8第…

寄生虫php版,-PHP版SEO最新教材版排名DeDeCms寄生虫V90繁殖

今天视频教程演示说明下PHP寄生虫服务端的使用。主要在很多搭建的过程中会出错,今天主要就讲解下寄生虫配置常见的问题。那么同样也可以看下我们之前的通用版寄生虫使用教程[通用版教程在文件夹中有],本教程是针对PHP版本的寄生虫服务端进行配置演示。继…

SpringMVC请求参数乱码问题

post 请求方式&#xff1a; 在 web.xml 中配置一个过滤器 <!-- 配置 springMVC 编码过滤器 --><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter…

MySQL中 JSON 数据类型应用

前言 今天接触到mysql中json数据类型&#xff0c;之前不知道有这个类型&#xff0c;今天学习一下。 JSON我相信大家都已经很熟悉了&#xff0c;但在 MySQL中&#xff0c;直至 5.7 版本中&#xff0c;才正式引入 JSON数据类型。在次之前&#xff0c;我们通常使varchar或text数…

如何修改matlab中的语句,求大神帮忙看一下这个语句怎么改!!!!!

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼clcclearWimread(e:\matlab\aaa\1.jpg);imshow (W);I rgb2gray(W); % 灰度处理imshow (I);title(灰度图像);Jimnoise(I,salt & pepper,0.2); %椒盐噪声figureimshow (J) ;title(椒盐噪声);Qimnoise(I,gaussian,0,0.01); %高斯…

MySql中json类型的使用___mybatis存取mysql中的json

MySql中json类型的使用 MySQL从5.7.8起开始支持JSON字段&#xff0c;这极大的丰富了MySQL的数据类型。也方便了广大开发人员。但MySQL并没有提供对JSON对象中的字段进行索引的功能&#xff0c;至少没有直接对其字段进行索引的方法。本文将介绍利用MySQL 5.7中的虚拟字段的功能…

百度下拉词+php,百度下拉词是如何生成的?

我们在百度搜索某一词汇的时候&#xff0c;都会在搜索框下面弹出一些相关性和搜索次数比较多的语句或词语&#xff0c;我们在百度上搜索一下&#xff0c;就可以看到用户平时搜索习惯&#xff0c;搜索爱好是什么。护发下拉很多小伙伴就又有疑问了&#xff1a;这些下拉词是根据什…

python元组赋值给变量,Python的赋值

一、序列解包多个赋值操作同时进行&#xff1a;赋值多个值后面再遇到对多个变量赋值时&#xff0c;就不需要对一个变量赋完值再对另一个变量赋值了&#xff0c;用一条语句就可以搞定&#xff0c;例如&#xff1a;再次赋值由输出结果看到&#xff0c;x和y的值交换了&#xff0c;…

微服务,你得知道这

目录 一、业务场景介绍 二、Spring Cloud核心组件&#xff1a;Eureka 三、Spring Cloud核心组件&#xff1a;Feign 四、Spring Cloud核心组件&#xff1a;Ribbon 五、Spring Cloud核心组件&#xff1a;Hystrix 六、Spring Cloud核心组件&#xff1a;Zuul 七、总结 概述…

python新手输出错误,Python 新手常犯错误(第一部分)

用一个可变的值作为默认值这是一个绝对值得放在第一个来说的问题。不仅仅是因为产生这种BUG的原因很微妙&#xff0c;而且这种问题也很难检查出来。思考一下下面的代码片段&#xff1a;def foo(numbers[]):numbers.append(9)print numbers在这里&#xff0c;我们定义了一个 lis…

分布式和微服务的区别

分布式和微服务的区别 1.颜老师&#xff0c;分布式和微服务有什么区别呢&#xff1f;网上说啥的都有&#xff0c;越看越晕了。 答&#xff1a;分布式的核心就一个字&#xff1a;拆。只要是将一个项目拆分成了多个模块&#xff0c;并将这些模块分开部署&#xff0c;那就算是分布…