如何通过HTTP POST请求发送Blob数据并附带JWT认证字符串参数?
问题分析与解决方案
你的代码目前无法正确发送Blob数据和认证参数,核心问题在于没有用正确的方式封装混合类型的请求体,同时请求头的处理逻辑不符合多类型数据传输的要求。以下是修正后的实现方案:
1. 用FormData封装请求参数
要同时发送字符串参数和Blob数据,必须使用FormData来封装,它会自动处理多类型数据的编码:
// 创建FormData实例并添加参数 const formData = new FormData(); formData.append('uname', user.uname); formData.append('authKey', user.authKey); // 若authKey是JWT,更建议放在请求头中(见下方说明) formData.append('video', qde.debrief.blob, 'video-file.mp4'); // 第三个参数可指定文件名称,便于后端识别 // 调用修正后的xhrRequest const xhr = await xhrRequest(`${serverIp}/api/file`, "POST", formData, 'multipart'); prom.push(xhr);
2. 修正xhrRequest函数
原函数存在请求体序列化错误、响应解析容错性差等问题,以下是优化后的版本:
function xhrRequest(url, type, body, header) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { let responseBody; // 兼容非JSON格式的响应,避免解析报错 try { responseBody = JSON.parse(xhr.response); } catch (e) { responseBody = xhr.response || "未知错误"; } // 统一处理成功/失败状态 resolve({ error: xhr.status !== 200, body: responseBody }); } } xhr.timeout = 5000; xhr.ontimeout = () => { resolve({ error: true, body: "连接服务器超时" }); } xhr.onerror = function () { resolve({ error: true, body: "服务器连接失败" }); } xhr.open(type, url, true); // --- 可选:JWT认证放在请求头(更规范安全)--- // 如果authKey是JWT令牌,建议改用请求头传递,注释掉上方FormData中的authKey后启用以下代码 // if (typeof body === 'object' && !(body instanceof FormData) && body.authKey) { // xhr.setRequestHeader('Authorization', `Bearer ${body.authKey}`); // delete body.authKey; // 从请求体中移除 // } if (type === "POST") { // 仅在发送普通urlencoded参数时手动设置请求头 if (header === 'application/x-www-form-urlencoded' && !(body instanceof FormData)) { xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); // 将普通对象序列化为urlencoded格式 body = new URLSearchParams(body).toString(); } // 发送FormData时,浏览器会自动设置正确的multipart/form-data头(包含boundary),无需手动设置 xhr.send(body); } else { xhr.send(); } }) }
关键说明
- FormData的必要性:直接发送包含Blob的普通对象会被浏览器转成
[object Object],完全无法解析;FormData会自动处理Blob的编码和边界分隔符,确保后端能正确解析文件。 - JWT认证的最佳实践:将JWT令牌放在
Authorization: Bearer <token>请求头中,比作为表单参数更安全,也符合RESTful规范。如果采用这种方式,只需在xhrRequest中添加设置请求头的逻辑,无需将authKey放入FormData。 - 请求头的自动处理:发送FormData时,不要手动设置
Content-Type: multipart/form-data,浏览器自动生成的头会包含必要的boundary参数,手动设置会导致后端解析失败。
内容的提问来源于stack exchange,提问作者Mitchell Day
相关产品推荐
相关产品推荐

