前端XMLHttpRequest get请求能不能在body中传参数?

文档

查看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);
    }
});
解释
  1. 默认配置

    • defaults 对象包含了默认的请求配置,如请求方法、URL、头部信息、数据、查询参数和回调函数。
    • 用户提供的配置会覆盖默认配置。
  2. 构建完整的 URL

    • 如果 options.query 存在,将其转换为查询字符串并附加到 url 上。
    • 使用 encodeURIComponent 对查询参数进行编码,确保特殊字符被正确处理。
  3. 设置请求方法和 URL

    • xhr.open(options.method, url, true):打开请求,true 表示异步请求。
  4. 设置请求头部

    • 使用 for 循环遍历 headers 对象,并调用 setRequestHeader 方法设置每个头部信息。
  5. 处理响应

    • onreadystatechange 事件处理程序检查 readyStatestatus,并在请求完成且状态码为 200-299 时调用 success 回调,否则调用 error 回调。
  6. 发送请求体

    • 如果是 POSTPUT 请求且数据类型为 FormData,直接发送 FormData 对象。
    • 否则,将数据转换为 JSON 字符串并发送。

通过这种方式,您可以灵活地使用 XMLHttpRequest 发送各种类型的 AJAX 请求,并支持传递自定义头部、不同形式的请求体和查询参数。

相关推荐
撸码到无法自拔几秒前
React:组件、状态与事件处理的完整指南
前端·javascript·react.js·前端框架·ecmascript
高山我梦口香糖1 分钟前
[react]不能将类型“string | undefined”分配给类型“To”。 不能将类型“undefined”分配给类型“To”
前端·javascript·react.js
代码cv移动工程师4 分钟前
HTML语法规范
前端·html
Elena_Lucky_baby27 分钟前
实现路由懒加载的方式有哪些?
前端·javascript·vue.js
Domain-zhuo27 分钟前
如何利用webpack来优化前端性能?
前端·webpack·前端框架·node.js·ecmascript
理想不理想v31 分钟前
webpack如何自定义插件?示例
前端·webpack·node.js
小华同学ai1 小时前
ShowDoc:Star12.3k,福利项目,个人小团队的在线文档“简单、易用、轻量化”还专门针对API文档、技术文档做了优化
前端·程序员·github
王解1 小时前
Vue CLI 脚手架创建项目流程详解 (2)
前端·javascript·vue.js
刘大浪1 小时前
vue.js滑动到顶便锁定位置
前端·javascript·vue.js
小金刚®1 小时前
构建简洁之美:我的第一个前端页面
前端