文档
查看mdn文档,文档XMLHttpRequest.send()有提到:
XMLHttpRequest.send() 方法接受一个可选的参数,其作为请求主体;如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null。
测试
一个简单的nodejs服务器
var http = require('http')
var server = http.createServer()
server.on('request', function (request, response) {
console.log('收到客户端的请求了,请求路径是:' + request.url)
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
response.write('hello')
response.write(' nodejs')
response.end()
})
server.listen(3000, function () {
console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})
一个简单的前端页面
<!DOCTYPE html>
<html lang="en">
<body>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/2.2.1/jquery.js "></script>
<script>
// 方法1,使用原生的XMLHttpRequest,get请求,send传数据
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:3000/method1', true);
xhr.send('{a:1}');
xhr.onload = function () {
console.log('123')
};
// 方法2,使用ajax的方式传数据
$.ajax({
url: "http://127.0.0.1:3000/method2",
method:'get',
data: {a:1}
}).done(function() {
$(this).addClass("done");
});
</script>
</html>
截图:
方法1:
明显没有入参{a:1}
方法2:
自动拼接到url中(从ajax文档也看出ajax会自动将get请求的参数带入到url中)
结论
前端XMLHttpRequest get请求不能在body中传参数,只能拼接到url中传参。
使用 XMLHttpRequest
封装 AJAX 请求,并支持传递自定义头部以及使用 FormData
传递参数,可以按照以下步骤进行。我们将创建一个通用的 ajax
函数,该函数接受多种参数,包括请求方法、URL、头部信息、请求体等。
封装 AJAX 函数
function ajax(options) {
// 默认配置
const defaults = {
method: 'GET',
url: '',
headers: {},
data: null,
query: null,
success: function(response) {},
error: function(error) {}
};
// 合并用户提供的配置
options = { ...defaults, ...options };
// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 构建完整的 URL
let url = options.url;
if (options.query) {
const queryStr = Object.keys(options.query).map(key =>
encodeURIComponent(key) + '=' + encodeURIComponent(options.query[key])
).join('&');
url += (url.includes('?') ? '&' : '?') + queryStr;
}
// 设置请求方法和 URL
xhr.open(options.method, url, true);
// 设置请求头部
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
// 处理响应
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
options.success(xhr.responseText);
} else {
options.error(xhr.statusText);
}
}
};
// 发送请求体
if (options.data instanceof FormData) {
xhr.send(options.data);
} else if (options.method.toUpperCase() === 'POST' || options.method.toUpperCase() === 'PUT') {
xhr.send(JSON.stringify(options.data));
} else {
xhr.send();
}
}
使用示例
1. 发送 GET 请求,带查询参数
ajax({
method: 'GET',
url: 'https://api.example.com/data',
headers: {
'Authorization': 'Bearer your-token'
},
query: {
param1: 'value1',
param2: 'value2'
},
success: function(response) {
console.log('GET Response:', response);
},
error: function(error) {
console.error('GET Error:', error);
}
});
2. 发送 POST 请求,传递 JSON 数据
ajax({
method: 'POST',
url: 'https://api.example.com/data',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token'
},
data: {
key1: 'value1',
key2: 'value2'
},
success: function(response) {
console.log('POST Response:', response);
},
error: function(error) {
console.error('POST Error:', error);
}
});
3. 发送 POST 请求,传递 FormData
const formData = new FormData();
formData.append('file', document.getElementById('file-input').files[0]);
formData.append('name', 'John Doe');
ajax({
method: 'POST',
url: 'https://api.example.com/upload',
headers: {
'Authorization': 'Bearer your-token'
},
data: formData,
success: function(response) {
console.log('FormData POST Response:', response);
},
error: function(error) {
console.error('FormData POST Error:', error);
}
});
解释
-
默认配置:
defaults
对象包含了默认的请求配置,如请求方法、URL、头部信息、数据、查询参数和回调函数。- 用户提供的配置会覆盖默认配置。
-
构建完整的 URL:
- 如果
options.query
存在,将其转换为查询字符串并附加到url
上。 - 使用
encodeURIComponent
对查询参数进行编码,确保特殊字符被正确处理。
- 如果
-
设置请求方法和 URL:
xhr.open(options.method, url, true)
:打开请求,true
表示异步请求。
-
设置请求头部:
- 使用
for
循环遍历headers
对象,并调用setRequestHeader
方法设置每个头部信息。
- 使用
-
处理响应:
onreadystatechange
事件处理程序检查readyState
和status
,并在请求完成且状态码为 200-299 时调用success
回调,否则调用error
回调。
-
发送请求体:
- 如果是
POST
或PUT
请求且数据类型为FormData
,直接发送FormData
对象。 - 否则,将数据转换为 JSON 字符串并发送。
- 如果是
通过这种方式,您可以灵活地使用 XMLHttpRequest
发送各种类型的 AJAX 请求,并支持传递自定义头部、不同形式的请求体和查询参数。