Ajax 示例

XMLHttpRequest

xhr对象用于与服务器交互。通过使用xhr对象可以在不刷新页面的情况下请求特定的URL,获取数据源,允许网页在不影响用户操作的情况下,更新页面的局部内容
可用获取的是HTTP以外的协议(file:// 和FTP),而不仅限于XML。但更到的会局限于安全等原因收到同源策略的影响
image.png
也就是说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

  1. const xhr = new XMLHttpRequest();
  2. xhr.responseType = "josn"
  3. xhr.response // {jsonSource:"xxx"}
  4. 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

https://fetch.spec.whatwg.org/#request-class

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对象的实例

取消请求

AbortController


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;