文档
查看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();// 构建完整的 URLlet 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;}// 设置请求方法和 URLxhr.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 请求,并支持传递自定义头部、不同形式的请求体和查询参数。