深入理解 Ajax,利用原生 JS 实现

Ajax 基本知识点

  • AJAX 全称为 Asynchronous JavaScript and XML(异步 JavaScript 和 XML),是一种创建交互式网页应用的网页开发技术
  • Ajax 最核心的依赖就是浏览器提供的 XMLHttpRequest 对象
  • Ajax 原理是通过 XMLHttpRequest 对象向服务器发出异步请求,从服务器获取数据,然后用 JavaScript 来操作 DOM 实现页面的局部刷新

XMLHttpRequest 常见的属性

  • onreadystatechange 每次状态改变时触发的事件
  • responseText 从服务器接受到的响应体(不包含头部),或者如果还没接受到数据的话,就是空字符串
  • responseXML 对请求的响应,解析为 XML 并作为 Document 对象返回
  • state 从服务器返回的数字代码,比如常见的 404(找不到)、 200(请求成功)500(服务器在执行请求时报错)
  • readyState HTTP 请求的状态,当一个 XMLHttpRequest 初次创建时,这个属性值从 0 开始,直到接收完整的 HTTP 响应,值增加到 4
  • 0(未初始化) 对象已建立,但是尚未初始化(尚未调用 open 方法)
  • 1(初始化) 对象已建立,open 方法已调用,尚未调用 send 方法
  • 2(发送数据) send 方法已调用,但是当前的状态及 http 请求头未知
  • 3(数据传送中) 已接受部分数据,因为响应及 http 请求头不全,这时通过 responseBody 和 responseText 获取部分数据会出现错误
  • 4(完成) 数据接收完毕,此时可以通过 responseXml 和 responseText 获取完整的响应数据
    在这里插入图片描述

Ajax 实现步骤

1. 创建 XMLHttpRequest 对象,也就是创建一个异步调用对象

let xmlHttp
// 考虑兼容 IE5、6 浏览器
if (window.XMLHttpRequest) {
	xmlHttp = new XMLHttpRequest()
} else {
	xmlHttp = new ActiveXObject('Microsoft.XMLHTTP')
}

2. 创建一个新的 HTTP 请求,指定该请求的方法、URL、验证信息

// 语法: XMLHttpRequest.open(method, URL, flag, name, password)
// method: HTTP 请求方式,有 get post head put delete 
// URL: HTTP 请求的 URL 地址
// flag: 可选参数,参数值为布尔值,true 表示异步请求,false 表示同步请求,默认为 true
// name: 该参数为可选参数,用于输入用户名。如果服务器需要验证,则必须使用该参数。
// password: 该参数为可选参数,用于输入密码。如果服务器需要验证,则必须使用该参数。

xmlHttp.open('GET', 'https://blog.csdn.net/qq_43778110/article/details/102507852', true)

// GET 请求参数需要拼接在 URL 后面
xmlHttp.open('GET', '/list?page=5', true)
xmlHttp.send()

// POST 请求数据是放在 send 里面
xmlHttp.open('POST', '/list', true)
xmlHttp.send('page=5&pageSize=10')

3. 设置响应 HTTP 请求状态变化的函数

xmlHttp.onreadystatechange = () => {
	// 判断XMLHttpRequest对象的readyState属性值是否为4,如果为4表示异步调用完成
	if (xmlHttp.readyState === 4) {
		// 设置获取数据的语句 xmlHttp.status === 200 说明服务器成功响应返回的结果
		if (xmlHttp.status === 200) {
			// 返回结果以字符串的形式输出
			document.write(xmlHttp.responseText)
			// 返回结果以 XML 形式输出
			document.write(xmlHttp.responseXML)
		}
	}
}

4. 发送 HTTP 请求

// 语法: XMLHttpRequest.send(data)
// 其中 data 是个可选参数,如果是 get 请求的数据写在 URL 中,那这里可以使用 null 来代替;如果是 post 请求,data 参数的格式与在 URL 中传递参数的格式类似
XMLHttpRequest.send('name=myName&value=myValue')

// 防止乱码: 服务器端设置 request.setCharacterEncoding('utf-8')
// post 请求需要额外设置请求头: 
XMLHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

// 请求发送后, send()会把 readyState 设置为 2,并触发 onreadystatechange 事件。
// 当所有的 HTTP 响应头部已经接收,send() 或后台线程把 readyState 设置为 3 并触发 onreadystatechange 事件。
// 当响应完成,send() 或后台线程把 readyState 设置为 4,并最后一次触发事件。

// 只有在使用了 send() 方法后。XMLHttpRequest 对象的 readyState 属性值才会开始变化,onreadystatechange 监听到 readyState 变化后才会执行

5. 获取异步调用的数据

if (xmlHttp.status === 200) {
	// 返回结果以字符串的形式输出
	document.write(xmlHttp.responseText)
	// 返回结果以 XML 形式输出
	dcoument.write(xmlHttp.responseXML)
}

6. 利用 JavaScript 和 DOM 实现页面局部更新

原生 JS 实现 Ajax 的封装

function myAjax (obj) {
	// get 方式传入时,将 data 内容进行拼接
	function splicStr (data) {
		let str = ''
		for (let i in data) {
			str = i + '=' + data[i]
		}
		return str
	}
	// 1. 创建 XMLHttpRequest 对象(注意浏览器兼容性)
	let xmlHttp
	if (window.XMLHttpRequest) {
		xmlHttp = new XMLHttpRequest()
	} else {
		xmlHttp = new ActiveXObject('Microsoft.XMLHTTP') // 兼容 IE 5、6
	}
	// 2. 初始化 HTTP 请求参数,只初始化并不会发送
	if (obj.method.toUpperCase() === 'GET') {
		// get 请求
		xmlHttp.open(obj.method.toUpperCase(), obj.url + '?' + splicStr(obj.data), typeof obj.async === 'boolean' ? obj.async ? true) // 路径拼接传参数
		// 3. 发送此次请求
		xmlHttp.send(null)
	} else if (obj.method.toUpperCase() === 'POST') {
		// post 请求
		xmlHttp.open(obj.method.toUpperCase(), obj.url, typeof obj.async === 'boolean' ? obj.async : true)
		// 表单提交,需要设置请求头
		xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
		// 3. 发送此次请求
		xmlHttp.send(obj.data) // post 请求传参
	}
	// 4. 利用 onreadystatechange 监听 readyState 的变化
	xmlHttp.onreadystatechange = () => {
		if (xmlHttp.readyState === 4 && xmlHttp.status === 200 {
			// success 回调
			success(xmlHttp.responseText)
		} else if (xmlHttp.readyState === 4 && xmlHttp.status !== 200) {
			// fail 回调
			fail()
		}
	}
}

// 调用 myAjax 函数
myAjax({
	url: '服务器接口地址',
	method: '请求方式',
	async: true // 异步请求
	data: {
		username: 'xiaoyi',
		password: '1226'
	},
	success (res) {
		console.log(res)
	},
	fail () {
		console.log('服务器请求失败')
	}
})

原型构造函数实现 Ajax

function MyAjax (obj) {
	this.xmlHttp = null
	this.method = obj.method || 'get'
	this.url = obj.url
	this.async = typeof obj.async === 'boolean' ? obj.async : true
	this.data = obj.data
	this.success = obj.success
	this.fail = obj.fail
	// 初始话创建 XMLHttpRequest 对象
	this.init()
}
myAjax.prototype = {
	init () {
		if (window.XMLHttpRequest) {
			this.xmlHttp = new XMLHttpRequest()
		} else {
			this.xmlHttp = new ActiveXObject('Microsoft.XMLHTTP')
		}
		this.openReq()
		this.watchReq()
	},
	openReq () {
		if (this.method.toUpperCase() === 'GET') {
			this.xmlHttp.open(this.method.toUpperCase(), this.url + '?' + this.splicStr(this.data), this.async)
			this.xmlHttp.send(null)
		} else if (this.method.toUpperCase() === 'POST') {
			this.xmlHttp.open(this.method, this.url, this.async)
			this.xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
			this.xmlHttp.send(this.data)
		}
	},
	watchReq () {
		this.xmlHttp.onreadystatechange = () => {
			if (this.xmlHttp.readyState === 4 && this.xmlHttp.status === 200) {
				// success 回调
				this.success(this.xmlHttp.responseText)
			} else if (this.xmlHttp.readyState === 4 && this.xmlHttp.status !== 200) {
				// fail 回调
				this.fail()
			}
		}
	},
	splicStr (data) {
		let str = ''
		for (let i in data) {
			str = i + '=' + data[i]
		}
		return str
	}
}
new MyAjax({
	url: 'https://blog.csdn.net/qq_43778110/article/details/102507852'
	method: 'get',
	data: {
		userName: 'huibao',
		password: '1217'
	},
	async: true,
	success (res) {
		console.log(res)
	},
	fail () {
		console.log('服务器请求失败')
	}
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值