二十四、网络请求与远程资源
创始人
2025-05-29 02:28:36
0

在这里插入图片描述

XML是过时的web规范产物,可以仅作了解,实际开发中应尽可能使用fetch()等

1.XMLHttpRequest对象

const xhr = new XMLHttpRequest();

使用XHR

const xhr = new XMLHttpRequest();
// 1.打开一个请求
xhr.open(method, url, isAsync); // 请求方法,请求路径,是否同步请求
// xhr.open('get', 'example.php', false);
// 2.发送一个请求
xhr.send(data); // 如果不需要发送数据,就send(null);
// 3.同步请求会在服务器响应后再继续执行,收到请求后,xhr对象上会填充如下属性
/**
responseText: 作为响应体的文本
responseXML: 如果相应内容为“text/html”或者“application/xml”, 则包含响应数据的XML DOM文档
status: 响应HTTP的状态
statusText: 响应HTTP的描述。
*/

同步请求:

/******** demo ************/
xhr.open("get", "example.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);
} else {alert("Request was unsuccessful: " + xhr.status);
}

异步请求:监听XMR对象上的readyState属性值的变化

readStaty属性值说明
0未初始化,还没调用open方法
1已打开,调用open(), 未调用send()
2已发送, 调用send(), 未响应
3接受中, 收到了部分响应
4完成,接受到了全部响应
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {if (xhr.readyState == 4) {if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}}
};
xhr.open("get", "example.txt", true);
xhr.send(null); // 如果想要取消异步请求,可以调用xhr.abort();

HTTP头部

XHR请求头部字段

字段含义
Accept浏览器可以处理的内容类型
Accept-Charset浏览器可以现实的字符集
Accept-Encoding浏览器可以处理的压缩编码类型
Accept-Language浏览器使用的语言
Connection浏览器和服务器连接的类型
Cookiecookie数据
Host发送请求的页面所在的域
Referer发送请求的页面的url
User-Agent浏览器的用户代理字符串

可以通过setRequestHeader(key, val)自定义请求头字段,必须在open()调用之后,send()调用之前调用。
获取响应头部的方法getResponseHeader(key)getAllResponseHeader()

GET

发送 GET 请求最常见的一个错误是查询字符串格式不对。查询字符串中的每个名和值都必须使用encodeURIComponent()编码

POST

POST 请求相比 GET 请求要占用更多资源。从性能方面说,发送相同数量的数据,
GET 请求比 POST 请求要快两倍

XMLHttpRequest Level2

FormData类型

xhr.send(formdata); // 不需要显示地设置头部

let data = new FormData();
data.append('name', 'coder');
超时

xhr对象上添加了timeout属性,用于设置超时时间

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {if (xhr.readyState == 4) {try {if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}} catch (ex) {// 假设由 ontimeout 处理}}
};
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000; // 设置 1 秒超时
xhr.ontimeout = function() {alert("Request did not return in a second.");
};
xhr.send(null);
overrideMimeType()方法

用于重写XHR响应的MIME类型,必须在send()之前调用

let xhr = new XMLHttpRequest();
xhr.open("get", "text.php", true);
xhr.overrideMimeType("text/xml");
xhr.send(null); 

2.进度事件

这些事件最初只针对xhr,现在也推广到其他api了

事件含义
loadstart在接收到响应的第一个字节时触发
progress在接受响应期间反复触发
error在请求出错时触发
abort调用abort()时
load在成功接受完响应时触发
loadend在通信完成时触发,且在error、abort、load之后

load事件

firefox在实现xhr时,增加load事件代替readystatechange事件, event.target=== xhr

let xhr = new XMLHttpRequest();
xhr.onload = function() {if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}
};
xhr.open("get", "altevents.php", true);
xhr.send(null); 

progress事件

onprogress事件接收到event对象,其target属性为XHR对象,且包含三个额外属性
lengthComputable: 布尔值,表示进度信息是否可用
position:接收到的字节数
totalSize: 响应的Content-Length头部定义的总字节数
必须在调用open()之前添加onprogress事件

let xhr = new XMLHttpRequest();
xhr.onload = function(event) {if ((xhr.status >= 200 && xhr.status < 300) ||xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}
};
xhr.onprogress = function(event) {let divStatus = document.getElementById("status");if (event.lengthComputable) {divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize + " bytes";}
};
xhr.open("get", "altevents.php", true);
xhr.send(null); 

3.跨源资源共享

受同源策略限制,XHR只能访问与发起请求的页面同一个域内的资源。
对于简单请求,请求头部有个Origin字段,包含请求页面的源,如果服务器决定响应请求,响应头应包含Access-Control-Allow-Origin(此行为会被自动触发)
跨域XHR对象还有一些额外的限制

  • 不能使用setRequestHeader()自定义头部字段
  • 不能发送和接受cookie
  • getAllResponseHeaders()始终返回空字符串

预检请求OPTIONS

请求头字段

字段含义
Origin
Access-Control-Request-Method请求希望使用的方法
Access-Control-Request-Headers请求可以接受的头部字段

响应头

字段含义
Access-Control-Allow-Origin
Access-Control-Allow-Methods允许的方法
Access-Control-Allow-Headers允许的头部字段
Access-Control-Max-Age缓存预检请求的秒数

凭据请求

默认情况下,跨域请求不会提供凭据
可以通过将xhr对象的withCredentials属性设为true来表明会发送凭据请求。此时响应头中应当包含Access-Control-Allow-Credentials:true

4.代替性跨源技术

图片探测

任何页面都可以跨域加载图片,而不用担心限制,
缺点是:只能发送get请求,无法获取服务器的相应数据

let img = new Image();
img.onload = img.onerror = function() {alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas"; 

JSONP

JSONP格式包括回调数据两部分,其调用是通过动态创建