// todo CSRF攻击/XSS攻击
1、Ajax
AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术)
- XMLHttpRequest api是Ajax的核心
- 什么是 XMLHttpRequest 对象?
XMLHttpRequest 对象用于在后台与服务器交换数据。所有现代的浏览器都支持 XMLHttpRequest 对象。
const xhr = new XMLHttpRequest();
// open(method, url, async, username, password)
// username 和 password 参数是可选的,为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。
xhr.open('GET', '/your-url', true);
xhr.send();
2、Axios
Axios基于Promise用于浏览器和Node.js的http客户端。
Axios的特性如下:
- 在浏览器中创建 XMLHttpRequests
- Make http requests from node.js
- 支持Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- JSON 数据的自动转换
- 客户端支持防止XSRF
- Axios的核心还是使用XHR来进行通信
3、Fetch
image.pngFetch 是一种新的原生 JavaScript API,目前大多数浏览器都支持。Fetch 允许您发出类似于 XMLHttpRequest。与 XMLHttpRequest 相比,它是对XMLHttpRequest API 的改进。Fetch 和 XMLHttpRequest 之间的主要区别在于 Fetch API 使用 Promise,因此避免了回调地狱。
Fetch特征如下:
- Fetch是基于Promise设计的。
- 不支持使用XHR,如果浏览器不支持Fetch则需要使用 XHR 实现。
- Fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理。
- Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: 'include'})。
- Fetch不支持abort,因为Fetch返回的是一个promise,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费。
- 当前IE9, Firefox, Chrome基本已经内置Fetch的全局方法。
- 如果不支持则用 XHR 实现,只要引入一个 polyfill 就可以了, github/fetch的源码实现。
- https://github.com/github/fetch/blob/master/fetch.js
// 摘抄代码片段
export function fetch(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
if (request.signal && request.signal.aborted) {
return reject(new DOMException('Aborted', 'AbortError'))
}
var xhr = new XMLHttpRequest()
function abortXhr() {
xhr.abort()
}
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
}
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
var body = 'response' in xhr ? xhr.response : xhr.responseText
setTimeout(function() {
resolve(new Response(body, options))
}, 0)
}
xhr.onerror = function() {
setTimeout(function() {
reject(new TypeError('Network request failed'))
}, 0)
}
xhr.ontimeout = function() {
setTimeout(function() {
reject(new TypeError('Network request failed'))
}, 0)
}
xhr.onabort = function() {
setTimeout(function() {
reject(new DOMException('Aborted', 'AbortError'))
}, 0)
}
function fixUrl(url) {
try {
return url === '' && global.location.href ? global.location.href : url
} catch (e) {
return url
}
}
xhr.open(request.method, fixUrl(request.url), true)
if (request.credentials === 'include') {
xhr.withCredentials = true
} else if (request.credentials === 'omit') {
xhr.withCredentials = false
}
if ('responseType' in xhr) {
if (support.blob) {
xhr.responseType = 'blob'
} else if (
support.arrayBuffer &&
request.headers.get('Content-Type') &&
request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1
) {
xhr.responseType = 'arraybuffer'
}
}
if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers)) {
Object.getOwnPropertyNames(init.headers).forEach(function(name) {
xhr.setRequestHeader(name, normalizeValue(init.headers[name]))
})
} else {
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value)
})
}
if (request.signal) {
request.signal.addEventListener('abort', abortXhr)
xhr.onreadystatechange = function() {
// DONE (success or failure)
if (xhr.readyState === 4) {
request.signal.removeEventListener('abort', abortXhr)
}
}
}
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
}
fetch.polyfill = true
if (!global.fetch) {
global.fetch = fetch
global.Headers = Headers
global.Request = Request
global.Response = Response
}
fetch的Requset对象等同于 XMLHttpRequest.send()
所以并不能确定Fetch底层使用的技术是什么,因为是浏览器厂商做的原生支持。
4、umi-request
umi-request是一个网络请求库,基于 Fetch 封装, 旨在为开发者提供一个统一的api调用方式, 简化使用, 并提供诸如缓存, 超时, 字符编码处理, 错误处理等常用功能。
支持的功能如下:
- url 参数自动序列化
- post 数据提交方式简化
- response 返回处理简化
- api 超时支持
- api 请求缓存支持
- 支持处理 gbk
- 类 axios 的 request 和 response 拦截器(interceptors)支持
- 统一的错误处理方式
5、wx-request
不支持Promise方式调用
wx.request({
url: 'your-url',
data: {
a: '',
},
header: {
'content-type': 'application/json'
},
success (res) {
console.log(res.data)
}
})
网友评论