XMLHttpRequest
xhr对象用于与服务器交互。通过使用xhr对象可以在不刷新页面的情况下请求特定的URL,获取数据源,允许网页在不影响用户操作的情况下,更新页面的局部内容
可用获取的是HTTP以外的协议(file:// 和FTP),而不仅限于XML。但更到的会局限于安全等原因收到同源策略的影响
也就是说xhr对象支持使用.onload;.onerror
属性的方式添加回调,也支持使用addEventListener
添加属性侦听器
readyState
表示对象在执行中进行到了那一个环节
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 下载中; responseText 属性已经包含部分数据。 |
4 | DONE | 下载操作已完成。 |
response&Text
response 属性表示此次请求响应的原始数据,responseText表示此次请求的DOMString表示形式
ex
const xhr = new XMLHttpRequest();
xhr.responseType = "josn"
xhr.response // {jsonSource:"xxx"}
xhr.responseText // '{"jsonSource":"xxx"}'
status&Text
status表示此次响应的statusCode码,比如200,404.。 statusText表示statusMessage,比如ok,error
withCredentials
bool, 用来指定跨域Access-Control
请求是否应带有授权信息,比如cookie或者授权的头信息
upload
表示上传进度,是一个XMLHttpRequestUpload
对象,可以添加事件绑定来追踪进度
事件 | 相应属性的信息类型 |
---|---|
onloadstart | 获取开始 |
onprogress | 数据传输进行中 |
onabort | 获取操作终止 |
onerror | 获取失败 |
onload | 获取成功 |
ontimeout | 获取操作在用户规定的时间内未完成 |
onloadend | 获取完成(不论成功与否) |
一个完整的XHR实例
const xhr = new XMLHttpRequest();
xhr.addEventListener("abort", () => { /**在xhr.abort调用的回调 */ })
xhr.addEventListener("readystatechange", (evl) => { /**在status调用的回调 */
evl.target // -> XMLHttpRequest 当前的实例
let res = evl.target;
res.response
res.responseText
res.status
res.statusText
})
xhr.addEventListener("error", () => { /**在发生错误调用的回调 */ })
xhr.addEventListener("loadend", () => { /**在请求结束时,不管成功或失败t调用的回调 */ })
xhr.addEventListener("loadstart", () => { /**在开始接受响应时调用的回调 */ })
xhr.addEventListener("progress", () => { /**在开始接受到更多的数据时调用的回调 */ })
xhr.addEventListener("timeout", () => { /**在开始请求超时时调用的回调 */ })
xhr.open(method, url,isAsync)
xhr.responseType = "json" // 设置响应类型
xhr.getAllResponseHeaders() // 返回响应头的raw信息。 是客户端被限制以外的头信息,不是全部
/*
1. 返回指定的响应头。 在w3c中规定,在客户端无法获取response中的set-cookie、set-cookie2两个字段
无论是是否跨域
2. 规定对于客户端可以获取的响应头只限与`Access-Control-Expose-Headers` 中指定的值
*/
xhr.getResponseHeader("key")
xhr.overrideMimeType("mimeType") // 覆盖由服务器返回的类型
xhr.setRequestHeader("key", "val") // 设置请求头
xhr.send() // 发送请求,如果请求是异步的,执行后立即返回
ActiveXObject
Fetch
Fetch 提供了对request和response对象的通用定义,可用用在更多的场景中
fetch 使用了Promise,不使用回调函数,大大的简化了写法,更简洁。 fetch Api采用了模块化的设计,API分散在多个对象上(Response/Request/Headers). 相比xhr,输入、输出、状态都在同一个接口管理,容易写出非常混乱的代码
fecth通过数据流处理数据,可以分块读取,有利于提高网站性能表现。减少内存占用,对于请求大文件或者网速慢的场景相当有用。xhr对象不支持流。所有的数据必须放在缓存里,不支持分块读取,必须等待全部拿到后,一次性的拿出来。
fetch 请求成功后,会得到一个Response对象
fetch底层使用的request对象的接口,所以参数与request对象参数一样
Response和Request对象都是BodyBody(mdn把body的介绍删除了,自行脑补)的实现
示例
const header = new Headers()
header.set("Content-Type","application/json")
fetch("request -> url",{
method:"post",
headers:header,
body:JSON.stringify({filterName:"xxx"})
})
.then(res => { // res -> body 对象的实例
return res.json()
})
.then(json => {
// 响应的json
})
.catch(err => {
// error 错误的捕获
})
//----->
fetch(new Request(/* init config*/))
.then(
r => {},
ex => {}
)
第二个参数为init对象和request对象的参数一致Request fetch也可以直接接受一个request对象的实例
取消请求
const cancelInstance = new AbortController();
fetch("request -> url",{
method:"post",
headers:header,
body:JSON.stringify({filterName:"xxx"}),
signal:cancelInstance.signal // with一个fetch
})
.then(
r => {},
ex => {}
)
// onClick ->
cancelInstance.abort() // 取消此次controller实例控制的fetch
Body
interface Body {
readonly body: ReadableStream<Uint8Array> | null;
readonly bodyUsed: boolean;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}
type BodyInit = Blob
| BufferSource
| FormData
| URLSearchParams
| ReadableStream<Uint8Array>
| string;