原生js 封装ajax请求超详细
Posted 流萤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生js 封装ajax请求超详细相关的知识,希望对你有一定的参考价值。
文章目录
XMLHttpRequest 对象
onreadystatechange 事件
setRequestHeader
处理响应
向服务器发送请求
思路说明
请求方式
完整代码
已经掌握AJAX基础的可以从思路说明开始看
XMLHttpRequest 对象
所有现代浏览器均支持 XMLHttpRequest
对象(IE5 和 IE6 使用 ActiveXObject)。
为了应对所有的现代浏览器:
let xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
onreadystatechange 事件
每当 readyState 改变时,就会触发 onreadystatechange
事件。
readyState 属性存有 XMLHttpRequest
的状态信息。
属性 | 描述 |
---|---|
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪 |
status | 200: "OK"404: 未找到页面 |
当 readyState 等于 4 且状态为 200 时,表示响应已就绪:
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var result = xmlhttp.responseText
try{
resolve(JSON.parse(result))
}catch (e) {
reject({errorMsg:\'数据格式错误\'})
}
} else {
// console.log(\'error:xmlhttp.status =\', xmlhttp.status)
reject(xmlhttp)
}
}
}
setRequestHeader
XMLHttpRequest.setRequestHeader()
是设置HTTP请求头部的方法。此方法必须在 open()
方法和 send()
之间调用。如果多次对同一个请求头赋值,只会生成一个合并了多个值的请求头。
如果没有设置 Accept 属性,则此发送出send() 的值为此属性的默认值/ 。
语法:
xmlhttp.setRequestHeader(header, value);
处理响应
XMLHttpRequest() 对象的几种类型的响应属性
属性 | 描述 |
---|---|
responseText | 获得字符串形式的响应数据。 |
responseXML | 获得 XML 形式的响应数据。 |
解析和操作包含 html 文档的 responseText 属性
解析这些HTML标记主要有三种方式:
- 使用
XMLHttpRequest.responseXML
属性 - 将内容通过
fragment.body.innerHTML
注入到一个 文档片段 中,并遍历 DOM 中的片段 - 如果预先知道 HTML 文档的内容,可以使用
RegExp
不推荐第三种方式,因为如果 HTML 代码发生轻微变化,该方法将可能失败,一般直接用XMLHttpRequest.responseXML
属性
向服务器发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法
open()
:规定请求的类型、URL 以及是否异步处理请求。
open(method,url,async)
参数说明:
- method:请求的类型;
- GET 或 POST url:文件在服务器上的位置
- async:true(异步)或 false(同步)
send()
:将请求发送到服务器。
send(string)
参数说明:
- string:仅用于 POST 请求
我的代码:
xmlhttp.open(arg.method || \'GET\', arg.url, true);
arg.headers = arg.headers || {};
for (let key in arg.headers){
xmlhttp.setRequestHeader(key, arg.headers[key]);
}
xmlhttp.send(arg.data);
思路说明
http请求有多种方式GET、POST、PUT...,先处理公共部分,封装一个createXMLHttp()方法
- 创建 XMLHttpRequest 对象
- 处理onreadystatechange事件,规定当服务器响应已做好被处理的准备时所执行的任务
- open() 规定请求的类型、URL 以及是否异步处理请求
- setRequestHeader() 设置请求头
- send() 将请求发送到服务器
createXMLHttp()方法接收一个对象arg 作为参数,返回一个Promise对象。
arg.method:请求的类型
arg.url:请求的url
arg.headers:请求的请求头,以对象形式存储
arg.data:仅用于POST请求
function createXMLHttp(arg) {
return new Promise((resolve,reject) => {
arg = arg || {}
let xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
//xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var result = xmlhttp.responseText
try{
resolve(JSON.parse(result))
}catch (e) {
reject({errorMsg:\'数据格式错误\'})
}
} else {
console.log(\'error:xmlhttp.status =\', xmlhttp.status)
reject(xmlhttp)
}
}
}
if(Vue.prototype.$ajax.interceptors && Vue.prototype.$ajax.interceptors.request){
Vue.prototype.$ajax.interceptors.request(arg)
}
xmlhttp.open(arg.method || \'GET\', arg.url, true);
arg.headers = arg.headers || {};
for (let key in arg.headers){
xmlhttp.setRequestHeader(key, arg.headers[key]);
}
xmlhttp.send(arg.data);
})
}
封装 post方法
拼接url、处理一下data的格式,调用createXMLHttp创建请求post
的data都是对象形式,处理起来比较简单, body = JSON.stringify(body)
就行了
Vue.prototype.$ajax.post = function post(url,body) {
url = Vue.prototype.$ajax.baseURL + url;
body = JSON.stringify(body)
let token = window.sessionStorage.getItem(\'token\')
token = (token != \'undefined\') ? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'POST\',
url,
headers:{
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
},
data:body
})
}
封装 get方法
原生AJAX的 GET 请求:
xmlhttp.open("GET","/try/ajax/demo_get.php?t=" + Math.random(),true);
xmlhttp.send();
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();
我的目标是除了上面字符拼接的方式,还能将对象作为参数发送请求
this.$ajax.get(\'/v1/user\', {
pageSize:this.pageSize,
pageNum:this.pageNum
})
this.$ajax.get(\'/v1/menuInfo?id=\'+1).then(res =>{})
this.$ajax.get(\'/v1/menuInfo?id=1&lname=Ford\').then(res =>{})
参数为对象时,要将key:value转为字符串key=value,多个参数中间用&符连接
需要先判断url的最后一位字符是否为\'?\',不是的话,最前面还要补上\'?\'
let paramsArray = []
for(let key in params){
paramsArray.push(key + \'=\' + params[key])
}
if(paramsArray.length){
url = url.indexOf(\'?\') > -1 ? url : (url + \'?\')
if (url.indexOf(\'?\') != url.length - 1){
url += \'&\'
}
url += paramsArray.join(\'&\')
}
get方法封装:
Vue.prototype.$ajax.get = function get(url,params) {
url = Vue.prototype.$ajax.baseURL + url;
let paramsArray = []
for(let key in params){
paramsArray.push(key + \'=\' + params[key])
}
if(paramsArray.length){
url = url.indexOf(\'?\') > -1 ? url : (url + \'?\')
if (url.indexOf(\'?\') != url.length - 1){
url += \'&\'
}
url += paramsArray.join(\'&\')
}
let token = window.sessionStorage.getItem(\'token\')
token = (token != \'undefined\') ? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'GET\',
url,
headers:{
\'accept\':\'application/json\',
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
}
})
}
为了方便使用,做成插件vue插件
//./plugin/MyAjax.js
var MyAjax = {};
MyAjax.install = function (Vue) {
Vue.prototype.$ajax = {
baseURL:\'xxxxxxxxxxxxxxxxxxxx\' //服务器域名:端口
}
}
module.exports = MyAjax;
//main.js
import myAjax from \'./plugin/MyAjax\'
Vue.use(myAjax)
请求方式
请求方式和axios差不多
//POST请求
this.$ajax.post(\'/v1/login\', {
userName:this.account,
passWord:this.password
}).then(res =>{
// console.log(res)
})
this.$ajax.post(\'/v1/group\',this.groupInfo).then(res =>{
if (!res.error){
// this.$router.back()
}
})
//GET请求
this.$ajax.get(\'/v1/xx?userName=\'this.userName).then(res =>{
// console.log(res)
})
this.$ajax.get(\'/v1/user\', {
pageSize:this.pageSize,
pageNum:this.pageNum
}).then(res =>{
console.log(res)
})
this.$ajax.get(\'/v1/menuInfo?id=\'+1).then(res =>{})
this.$ajax.get(\'/v1/menuInfo?id=1&lname=Ford\').then(res =>{})
完整代码
var MyAjax = {};
MyAjax.install = function (Vue) {
Vue.prototype.$ajax = {
baseURL:\'xxxxxxxxxxxxxxxxxxxx\'
}
function createXMLHttp(arg) {
return new Promise((resolve,reject) => {
arg = arg || {}
let xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {// code for IE6, IE5
//xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var result = xmlhttp.responseText
try{
resolve(JSON.parse(result))
}catch (e) {
reject({errorMsg:\'数据格式错误\'})
}
// console.log( Vue.prototype.$ajax.result)
} else {
console.log(\'error:xmlhttp.status =\', xmlhttp.status)
reject(xmlhttp)
}
}
}
if(Vue.prototype.$ajax.interceptors && Vue.prototype.$ajax.interceptors.request){
Vue.prototype.$ajax.interceptors.request(arg)
}
xmlhttp.open(arg.method || \'GET\', arg.url, true);
arg.headers = arg.headers || {};
for (let key in arg.headers){
xmlhttp.setRequestHeader(key, arg.headers[key]);
}
xmlhttp.send(arg.data);
})
}
Vue.prototype.$ajax.get = function get(url,params) {
url = Vue.prototype.$ajax.baseURL + url;
let paramsArray = []
for(let key in params){
paramsArray.push(key + \'=\' + params[key])
}
if(paramsArray.length){
url = url.indexOf(\'?\') > -1 ? url : (url + \'?\')
if (url.indexOf(\'?\') != url.length - 1){
url += \'&\'
}
url += paramsArray.join(\'&\')
}
let token = window.sessionStorage.getItem(\'token\')
token = (token != \'undefined\') ? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'GET\',
url,
headers:{
\'accept\':\'application/json\',
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
}
})
}
Vue.prototype.$ajax.post = function post(url,body) {
url = Vue.prototype.$ajax.baseURL + url;
body = JSON.stringify(body)
let token = window.sessionStorage.getItem(\'token\')
token = (token != \'undefined\') ? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'POST\',
url,
headers:{
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
},
data:body
})
}
Vue.prototype.$ajax.put = function put(url,body) {
url = Vue.prototype.$ajax.baseURL + url;
body = JSON.stringify(body)
let token = window.sessionStorage.getItem(\'token\')
token = token? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'PUT\',
url,
headers:{
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
},
data:body
})
}
Vue.prototype.$ajax.DELETE = function DELETE(url,body) {
url = Vue.prototype.$ajax.baseURL + url;
body = JSON.stringify(body)
let token = window.sessionStorage.getItem(\'token\')
token = token? JSON.parse(token) : \'\'
return createXMLHttp({
method:\'DELETE\',
url,
headers:{
\'Content-type\':\'application/json;charset=utf-8\',
\'token\': token
},
data:body
})
}
}
module.exports = MyAjax;
以上是关于原生js 封装ajax请求超详细的主要内容,如果未能解决你的问题,请参考以下文章