如何计算discord.js带附件消息的请求总大小以判断是否符合限制
Discord带附件消息预校验实现方案
核心问题说明
Discord的上传限制是针对整个发送请求的总大小,而非单个附件大小。你测试时8MB差1字节的文件仍然发送失败,就是因为请求里还包含了消息payload、multipart表单的边界、附件元数据等额外开销,加总后超出了阈值。仅校验单附件大小的方式自然会不准确。
总请求大小计算方法
你可以通过预构造和发送请求完全一致的multipart/form-data表单来获取准确的总大小,不用真的发请求,只计算长度即可:
- 首先获取对应服务器的上传阈值:无boost服务器为8MB(8388608字节),1级boost为50MB,2级boost为100MB。
- 用你实际发请求时使用的表单构造库(避免不同库的边界规则不同导致误差),把要发送的所有内容都放进表单:
- 消息内容、嵌入、组件等信息存到
payload_json字段 - 所有附件按API要求的
files[N]格式加入表单,同时带上文件名等元信息
- 消息内容、嵌入、组件等信息存到
- 直接读取构造完成的表单的
Content-Length值,就是实际发送请求的总大小。
预校验示例代码(Node.js 环境)
const fs = require('fs'); const { FormData } = require('formdata-node'); const { blobFromSync } = require('node-fetch'); // 替换为当前服务器对应的上传阈值,无boost为8*1024*1024 const MAX_ALLOWED_SIZE = 8388608; // 预留1KB冗余,避免环境差异导致的微小误差 const RESERVED_SIZE = 1024; // 构造消息内容 const messageData = { content: "测试带附件的消息", // 如有embeds、components等字段,都放在这里 }; // 构造和发送时完全一致的表单 const form = new FormData(); form.set('payload_json', JSON.stringify(messageData)); // 添加附件,索引从0开始递增 const testFile = blobFromSync('./test', 'application/octet-stream'); form.set('files[0]', testFile, 'test'); // 获取总大小 const totalRequestSize = form.getSync('Content-Length'); if (totalRequestSize <= MAX_ALLOWED_SIZE - RESERVED_SIZE) { // 大小符合要求,执行发送逻辑 msg.channel.send({ content: messageData.content, files: [{ attachment: fs.readFileSync('test'), name: 'test' }] }).catch(console.error); } else { // 超出大小,提前处理:比如压缩附件、拆分发送、提示用户 console.log(`请求总大小为${totalRequestSize}字节,超出最大允许值,无法发送`); }
注意事项
- 一定要用你实际发请求的同一个库构造计算用的表单,不同库生成的multipart边界不同,会导致大小计算有偏差
- 预留少量冗余空间可以进一步提高校验准确率,避免特殊场景下的额外开销导致校验通过但仍然发送失败
内容的提问来源于stack exchange,提问作者0x464e
相关产品推荐
相关产品推荐

