XMLHttpRequest.send() 方法深度解析
词源与功能定位
send() 方法名称源自其核心功能:
send(发送):体现其将客户端请求数据传输至服务器的动作本质
词源可追溯至TCP/IP协议中的"send packet"概念,反映底层网络传输行为
该方法用于实际发起HTTP请求,将open()方法初始化的请求发送到服务器,是XHR通信流程中的关键执行环节
语法结构详解
完整方法签名:
void send(optional (Document or BodyInit)? body = null);
参数解析
body (可选)
取值与语义:
特殊说明:
GET请求必须传入
null或省略参数(部分旧版浏览器要求显式传null)POST请求体需配合
setRequestHeader()设置Content-Type
方法示例与输出
基础GET请求
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onload = () => console.log(xhr.responseText);
xhr.send(); // 等效于xhr.send(null)输出流程:
建立TCP连接(readyState=1)
发送空请求体(无body)
接收响应后触发onload(readyState=4)
完整POST示例
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/submit');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
console.log('响应数据:', xhr.response);
}
};
xhr.send(JSON.stringify({ id: 123, name: "测试" }));输出结果:
成功:返回服务器处理后的JSON响应
失败:触发onerror事件
应用场景分析
1. 表单数据提交
const formData = new FormData(document.getElementById('myForm'));
xhr.open('POST', '/submit');
xhr.send(formData); // 自动设置multipart/form-data:ml-citation{ref="8" data="citationList"}2. 文件上传进度监控
xhr.upload.onprogress = (e) => {
const percent = (e.loaded / e.total * 100).toFixed(2);
console.log(`上传进度: ${percent}%`);
};
xhr.open('POST', '/upload');
xhr.send(file);:ml-citation{ref="2,9" data="citationList"}3. 大文件分块传输
const chunk = file.slice(offset, offset + CHUNK_SIZE);
xhr.open('POST', `/upload?name=${file.name}&offset=${offset}`);
xhr.send(chunk);:ml-citation{ref="9" data="citationList"}注意事项
调用顺序:
必须在
open()之后调用重复调用会触发
InvalidStateError同步请求限制:
主线程同步调用会导致UI冻结(现代浏览器已废弃该特性)
超时处理:
xhr.timeout = 5000; // 5秒超时
xhr.ontimeout = () => console.error('请求超时');:ml-citation{ref="5" data="citationList"}安全限制:
跨域请求需服务器配置CORS
禁止修改敏感请求头(如Cookie、Host等)
综合比较表
底层机制
网络层行为:
调用时创建HTTP请求报文
对非简单请求触发CORS预检
状态机转换:
stateDiagram-v2 OPENED --> HEADERS_RECEIVED: send() HEADERS_RECEIVED --> LOADING: 接收响应头 LOADING --> DONE: 接收完成
性能优化:
复用XHR对象减少TCP握手开销
大文件使用分块传输
现代替代方案
Fetch API等效实现
// 对应xhr.send(JSON.stringify(data))
fetch('/api', {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
});:ml-citation{ref="10,11" data="citationList"}异常处理指南
网络错误:
xhr.onerror = () => console.error('网络连接失败');状态码检查:
if(xhr.status >= 400) {
console.error(`请求失败: ${xhr.statusText}`);
}:ml-citation{ref="4,7" data="citationList"}超时处理:
xhr.ontimeout = () => retryRequest();
通过全面掌握send()方法的特性和使用模式,开发者可以构建更健壮的异步通信系统,满足现代Web应用的数据交互需求