# 实现 Ajax
# 代码实现
function ajax({
url = '',
type = "GET",
data = null,
success = (response) => {},
error = () => {},
} = {}) {
type = (type || 'GET').toUpperCase()
data = data || {}
// 避免特殊字符,对 value 进行 encode
const dataStr = Object.keys(data).reduce((res, key, i, keys) => {
res += `${key}=${encodeURIComponent(data[key])}${i < keys.length - 1 ? '&' : ''}`
return res
}, '')
const xhr = new XMLHttpRequest()
// 监听事件,只要 readyState 的值变化,就会调用 readystatechange
xhr.onreadystatechange = function () {
// readyState 属性表示请求/响应过程的当前活动阶段
// 4 为完成,已经接收到全部响应数据
if (xhr.readyState === 4) {
// status: 响应的 HTTP 状态码,以 2 开头的都是成功
const status = xhr.status
if (status >= 200 && status < 300) {
let response = null
// 接收数据的内容类型
const 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 // 字符串响应
}
// 成功回调函数
success && success(response)
} else {
// 失败回调函数
error && error(status)
}
}
}
// 连接和传输数据
if (type === 'GET') {
// open 三个参数分别是:请求方式、请求地址、是否异步请求
const symbol = url.indexOf('?') > -1 ? '&' : '?' // 判断 url 有没有 ?, 有的话就用 & 连接 data
xhr.open(type, url + symbol + dataStr, true)
xhr.send(null)
} else {
xhr.open(type, url, true)
// 设置提交时的内容类型
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
xhr.send(data) // 传输数据
}
}