const xhr = new XMLHttpRequest()
使用步骤:
xhr.open(method,url,true) xhr.send(data) xhr.onreadystatechange常用的 xhr 属性:
xhr.status: 状态码,成功 200xhr.statusText: 状态描述,“OK”xhr.responseText: 响应体文本xhr.readyState: 值为 4 表示已经获取到响应let xhr = new XMLHttpRequest();
const method = "get";
const url = "http://localhost:3000/";
// 1. 定义请求方法,请求url,是否是异步
xhr.open(method, url, true);
// 2. 真正发送请求,send接收请求数据
xhr.send(null);
// xhr的readystatechange事件
// xhr.readyState:4表明已获取到响应
// xhr.status 表示响应的状态码,200表示成功
// xhr.statusText 表示响应状态的描述,如果是200,则对应是"OK"
// xhr.responseText 表示作为响应体返回的文本
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log("请求成功,响应数据:>>", xhr.responseText);
}
}
};
HTTP 头部
默认 xhr 会发送以下头部:
Accept:浏览器可以处理的内容类型,如:*/*Accept-Charset:浏览器可以显示的字符集Accept-Encoding:浏览器可以显示的字符集,如:gzip, deflate, brAccept-Language:浏览器使用的语言,如:zh-CN,zh;q=0.9,en-GB;q=0.8,en-US;q=0.7,en;q=0.6Connection:浏览器与服务器的连接类型,keep-aliveCookie:页面中设置的 CookieHost:发送请求的页面所在的域,localhost:3000Referer:发送求情的页面的 URI,拼错了(将错就错,正确是 Referrer),User-Agent:浏览器的用户代理字符串。设置自定义 HTTP 请求头
在 xhr.open()和 xhr.send()之间可以设置自定义请求头
xhr.setRequestHeader(headerName,value)
获取响应头
xhr.getResponseHeader(‘headername’),获取指定响应头xhr.getAllResponseHeaders(),获取所有响应头,返回字符串 GET 请求get 请求添加的查询字符串,每个 key 和 value 都必须经过 encodeURIComponent()编码,以&分隔
xhr.open("get", "example.php?name1=value1&name2=value2", true);
POST 请求
POST 请求主要是用于保存数据,因此必须设置 Content-Type,POST 请求的请求体可以包含很多种数据格式,
Content-Type 的值:
application/x-www-form-urlencoded,请求体数据就是提交表单时的数据格式,类似 name1=value1&name2=value2 这种格式的字符串application/json,json 格式// 1. 定义请求方法,请求url,是否是异步
xhr.open("post", url, true);
// post请求,必须设置请求体数据类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 2. 真正发送请求,send接收请求数据
xhr.send("name=dragon&age=18");
XMLHttpRequest level2
FormData 类型
FormData 类型便于表单序列化,也便于创建与表单类似格式的数据然后通过 XHR 发送,
不再需要给 XHR 对象显式设置任何请求头部了。XHR 对象能够识别作为 FormData 实例传入的数据类型并自动配置相应的头部。
const data = new FormData();
data.append("name", "dragon");
data.append("age", 10);
// 1. 定义请求方法,请求url,是否是异步
xhr.open("post", url, true);
// 2. 真正发送请求,send接收请求数据,可以是FormData
xhr.send(data);
超时
设置超时,触发超时事件
xhr.timeout = 1000; // 设置1 秒超时
xhr.ontimeout = function () {
alert("Request did not return in a second.");
};
进度事件
loadstart,接收到响应第一个字节时progress,接收期间error,错误abort,调用 xhr.abort()load,成功接受完响应时loadend,通信完成,且在 error,abort 或 load 之后触发每次请求都会首先触发 loadstart 事件,之后是一个或多个 progress 事件,接着是 error、abort=或 load 中的一个,最后以 loadend 事件结束。 跨域资源共享
跨源资源共享(CORS,Cross-Origin Resource Sharing)定义了浏览器与服务器如何实现跨源通信。CORS 背后的基本思路就是使用自定义的 HTTP 头部允许浏览器和服务器相互了解,以确实请求或响应应该成功还是失败。
预检请求
简单请求:
GET,简单的 POST,HEAD
简单的 post 请求指 content-type 为以下这些值的
text/plainmultipart/form-dataapplication/x-www-form-urlencoded 跨域技术不依赖 CORS,也可以通过能够执行跨域请求的 DOM 特性来实现 AJAX
图片探测图片探测是利用标签实现跨域通信的最早的一种技术.设置 onload 和 onerror 事件.
图片探测频繁用于跟踪用户在页面上的点击 *** 作或动态显示广告。当然,图片探测的缺点是只能发
送 GET 请求和无法获取服务器响应的内容。这也是只能利用图片探测实现浏览器与服务器单向通信的
原因。
let img = new Image();
img.onload = function () {
alert("done");
};
img.onerror = function () {
alert("done");
};
img.src = "http://localhost:3000/";
JSONP
JSONP 调用是通过动态创建 script 元素并为 src 属性指定跨域 URL 实现的。实际上就是通过 script 拉取服务端代码.缺点是不安全,且无法确定是否请求失败,很少使用了.
JSONP 是“JSON with padding”的简写,是在 Web 服务上流行的一种 JSON 变体。JSONP 看起来 跟 JSON 一样,只是会被包在一个函数调用里.
JSONP 格式包含两个部分:回调和数据.
callback({ “name”: “Nicholas” });
客户端代码:
// 客户端定义一个函数,接收响应数据
function handleJSONP(res) {
console.log(res);
}
const script = document.createElement("script");
// 客户端与后端约定以callback的值确定调用的函数名称
script.src = "http://localhost:3000?callback=handleJSONP";
document.body.insertBefore(script, document.body.firstChild);
服务端代码:
router.get("/", async (ctx) => {
// 通过callback获取回调函数名称
const cbName = ctx.query.callback;
const data = "hello world";
//返回格式 callback(data)
ctx.body = `${cbName}(${JSON.stringify(data)})`;
});
Fetch API
能替代 XHR 对象,并且能在 Web Woker 中使用,必须是异步
基本用法fetch()方法暴露在全局作用域,包括主页面执行线程,模块和工作线程
1. 发送请求
fetch(url),默认是 get 请求,返回一个 promise,该 promise 会 resovle 一个 response 对象,可通过它取得响应的资源
fetch(url).then((response) => {
console.log(response); //response.status 200 状态码,response.body是一个ReadableStream,响应内容
// 调用response.text方法,返回一个promise,resolve响应的数据
response.text().then((data) => {
console.log(data); //
});
});
2. 读取响应
response 对象通过以下方法获取响应数据,均返回 resolve 数据的 Promise
fetch(url).then((response) => {
response.text().then((data) => {
console.log(data);
});
});
3. 处理状态码和请求失败
fetch API 可以通过 Response 对象的stauts(状态码)和statusText(状态文本),检查响应状态
响应状态
以下的状态 fetch()返回的 promise 还是会被 resolve
属性 | 成功 | 资源不存在 | 服务器错误 |
---|---|---|---|
response.stauts | 200 | 404 | 500 |
response.statusText | OK | Not Found | Internal Server Error |
response.ok | true | false | false |
重定向时的 response
会发生两次网络请求,最后 response.stauts 是 200,且 response.redirected 是 true
fetch()返回的 promise 被 reject 的情况
跨域,无网络链接,HTTPS 错配或者超时等情况导致 promise 被 reject 拒绝
fetch(url)
.then((response) => {
console.log(response);
})
.catch((e) => {
// 捕获reject错误
console.log(e);
});
4. 自定义选项
fetch(url,init)
init 对象的键值如下:
键 | 值 |
---|---|
body | 请求体,Blob,FormData,String,BufferSource,URLSearchParams,ReadableStream |
method | 请求方法,GET,POST,PUT,DELELTE,OPTION,HEAD,默认是 GET |
headers | 请求头,值是 Header 对象或者常规的对象,默认是不含键值对的 Header 对象,但浏览器仍然会发送一些头部 |
cache | 用于控制浏览器与 HTTP 缓存的交互,默认是 Default |
credentials | 用于指定外发请求时如何包含 cookie,默认是 same-origin,同源时才发送 cookie |
keepalive | 用于指示浏览器允许请求存在时间超出页面生命周期,默认是 false |
mode | 请求模式,用于指示跨域请求的响应是否有效,以及客户端可以读取多少响应,默认是 cors,允许跨域 |
signal | 值是 AbortSignal 的实例,用于支持中断请求 |
1. 发送 JSON 数据
JSON.stringify,POST,application/json
const headers = new Headers({
"Content-Type": "application/json", // post请求,必须设置该Content-Type
});
fetch(url, {
method: "POST", //指定请求HTTP方法
body: JSON.stringify({ foo: "bar" }), // 在浏览器中的payload,是Request Payload类型
headers,
}).then((response) => {
console.log(response);
});
2. 在请求体中发送参数
可以发送任意参数,application/x-www-form-urlencoded,name1=value1&name2=value2
const headers = new Headers({
"Content-Type": "application/x-www-form-urlencoded", // post请求,必须设置该Content-Type
});
fetch(url, {
method: "POST",
body: "foo=bar&baz=qux", //在浏览器的开发者工具中,看到的是FormData类型,因为是模拟表单提交
headers,
}).then((response) => {
console.log(response);
response.json().then(console.log); //{foo: 'bar', baz: 'qux'}
});
3. 发送文件
const url = "/post";
const data = new FormData();
data.append("image", File对象1);
data.append("image", File对象2);
fetch(url, {
method: "POST",
body: data, // 如果是FormData,默认自动会设置Content-Type,
}).then((response) => {
console.log(response);
response.json().then(console.log); //{foo: 'bar', baz: 'qux'}
});
4. 加载 Blob 文件
const url = "/img.jpg";
fetch(url).then((response) => {
console.log(response);
response.blob().then((blob) => {
// 根据blob创建objectURL
const url = window.URL.createObjectURL(blob);
const img = document.createElement("img");
img.src = url;
document.body.appendChild(img);
});
});
5. 发送跨源请求
从不同的源请求资源,响应要包含 CORS 头部才能保证浏览器收到响应.
6. 中断请求
Fetch API 支持通过 AbortController/AbortSignal 对中断请求。调用 AbortController.
abort()会中断所有网络传输,特别适合希望停止传输大型负载的情况。中断进行中的 fetch()请求会
导致包含错误的拒绝。
在 fetch()第二个参数设置 signal,调用 AbortController.abort()
const url = "/img.jpg";
const abortController = new AbortController();
//fetch()第二个参数设置 signal为abortController.signal
fetch(url, { signal: abortController.signal }).catch((e) => {
console.log("中断了请求"); //中断了请求
});
// 0ms后中断请求
setTimeout(() => {
abortController.abort();
}, 0);
Headers 对象
Headers 对象存在 request,response 实例上,也可以通过 new Headers()创建
1.Headers 与 Map 的相似之处
和 Map 类型相似,具有 get(),set(),has(),delete()等实例方法,可以被迭代,有 keys(),values(),entries()接口
2. Headers 独有特性
可以通过键值对形式的对象初始化,append 同个键,会以","的分隔符拼接多个值
3. 头部护卫
某些 HTTP 头部不可以被客户端修改
1. 创建 Request 对象
new Request(url),new Request(url,init)
2. 克隆 Request 对象
前提: bodyUsed属性不为true,否则无论哪种方式是克隆不成功的
request对象如果被new Request()或者fetch()使用过,那么就reqeust.bodyUsed就变为true,不能再被fetch()使用
let r1 = new Request("http://localhost:3000", {
method: "POST",
body: JSON.stringify({ name: "dragon" }),
});
let r2 = new Request(r1);
console.log(r1.bodyUsed); // true,由于使用了new Request(r1),r1.bodyUsed就会被标记为ture,
console.log(r2.bodyUsed); // false
fetch(r2).then((response) => {
console.log(r2.bodyUsed); //true
});
建议通过clone方法,只有request.bodyUsed为false的情况下才能克隆成功,否则报错
let r = new Request("http://localhost:3000", {
method: "POST",
body: JSON.stringify({ name: "dragon" }),
});
r.clone(); //不会报错
r.text(); // 调用text(),bodyUsed变为true,再次克隆则会报错
r.clone(); // 报错
new Request(r1); // 报错
在fetch()中使用request对象
fetch(request,init),也可以传Request对象,并且再传init对象覆盖原配置.有请求体的Request只能在fetch()中使用一次,调用后request的bodyUsed变为true,如果想基于同一个请求体发送多次请求,在请求前先clone以下
let r = new Request("http://localhost:3000", {
method: "POST",
body: "foobar",
});
console.log(r.bodyUsed); //false
fetch(r);
console.log(r.bodyUsed); //true
fetch(r); //报错,TypeError: Failed to execute 'fetch' on 'Window': Cannot construct a Request with a Request object that has already been used.
// 先克隆再请求
// 3 个都会成功
fetch(r.clone());
fetch(r.clone());
fetch(r);
Response 对象
创建Response对象new Response(body?,init?)
let r = new Response();
let r2 = new Response(JSON.stringify({ foo: "bar" }), {
status: 200,
statusText: "OK",
});
console.log(r2);
//body: (...)
//bodyUsed: true
//headers: Headers {}
//ok: true
//redirected: false
//status: 200
//statusText: "OK"
//type: "default"
//url: ""
r2.text().then(console.log);
大多数情况下,都是通过fetch()返回的promise来resolve一个response对象,另外还有两个静态方法Response.redirect(),Response.error()
2. 读取响应状态
Response 对象包含一组只读属性,描述了请求完成后的状态.
属性 | 值 |
---|---|
headers | 响应包含的Headers 对象 |
ok | 布尔值,表示HTTP 状态码的含义。200~299 的状态码返回true,其他状态码返回false |
redirected | 布尔值,表示响应是否至少经过一次重定向 |
status | 整数,表示响应的HTTP 状态码 |
statusText | 字符串,包含对HTTP 状态码的正式描述.这个字段可能是空字符串 |
type | basic:表示标准的同源响应 cors:表示标准的跨源响应 |
url | 包含响应URL 的字符串。对于重定向响应,这是最终的URL |
3. 克隆Response对象
克隆Response 对象的主要方式是使用clone()方法,这个方法会创建一个一模一样的副本,不会覆盖任何值.
let r1 = new Response("foo bar");
let r2 = r1.clone();
r1.text();
r1.clone(); // 报错,响应体已使用,bodyUsed为true的响应对象不能再次克隆
r1.text(); // 报错了, 带有响应体的响应对象只能读取一次,再次读取会报错
//想多次读取,则先克隆
r2.clone().arrayBuffer().then(console.log);
r2.clone().text().then(console.log);
r2.clone().blob().then(console.log);
Request,Response 及 Body 混入
Request 和Response 都使用了Fetch API 的Body 混入,提供了只读的body 属性(实现为ReadableStream)、只读的bodyUsed 布尔值(表示body 流是否已读)和一组方法
text()json()formData()arrayBuffer()blob()response.text().then(text=>{})
response.json().then(json=>{})
response.formData().then(formData=>{})
response.arrayBuffer().then(arrayBuffer=>{})
response.blob().then(blob=>{})
Beacon API
普通的XHR对象或者fecth请求会在页面unload卸载后就中断,而navigator.sendBeacon()就不会,这个简单的方法接收一个URL 和一个数据有效载荷参数,并会发送一个POST请求。可选的数据有效载荷参数有ArrayBufferView、Blob、DOMString、FormData 实例。如果请求成功进入了最终要发送的任务队列,则这个方法返回true,否则返回false.
特点:
在页面的生命周期的任何时候都能使用浏览器关闭也能使用会携带cookie状态码,超时或其他原因造成失败是不透明的,不能通过编程方式处理.let isSended = navigator.sendBeacon(
"http://localhost:3000",
JSON.stringify({ foo: "bar" })
);
WebSocket
Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通
API
let ws = new WebSocket(“ws://localhost:3000”);
// 创建WebSocket实例,参数ws开头的url
let ws = new WebSocket("ws://localhost:3000");
ws.onmessage = function (e) {
// 服务器推送的数据,data可能是blob或arrayBuffer
console.log(e.data);
};
ws.onopen = function () {
ws.send("我是客户端的socket消息");
console.log(ws.readyState);
};
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)