You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

application/dns-message采用何种编码?DoH请求体解码异常求助

问题核心原因

  1. 混淆了DoH两种请求方式的编码规则
    DoH标准中base64url编码仅用于GET请求的dns查询参数,你当前拿到的是POST请求的application/dns-message格式请求体,本身就是原始DNS二进制报文,不需要做任何base64转换操作,你执行的「ArrayBuffer转base64再做base64url解码」属于多余操作,直接破坏了原始报文结构。
  2. 错误将二进制DNS报文直接转为可读字符串
    DNS报文是按固定二进制协议结构封装的,并非纯文本内容,直接把二进制字节转成字符串必然会出现大量不可见字符,看起来就是乱码,你需要按DNS协议规范逐字段解析报文内容。

解决步骤

  • 第一步:区分请求类型处理报文
    • 若为POST请求:直接使用接收到的Uint8Array原始数据即可,无需任何编码转换
    • 若为GET请求:从URL的dns查询参数中获取base64url编码的字符串,先将其转为标准base64格式,再解码得到二进制DNS报文
  • 第二步:按DNS协议结构解析报文
    你示例中的解码结果里的apnx-matchdotomicom已经是DNS请求的域名部分可读内容,只是缺少了DNS报文里的标签长度分隔符,你可以按以下逻辑解析域名字段:
function parseDomainName(buffer, offset) {
  let domain = [];
  let len = buffer[offset];
  while (len !== 0) {
    // 处理指针跳转(压缩域名的情况)
    if ((len & 0xC0) === 0xC0) {
      const pointer = ((len & 0x3F) << 8) | buffer[offset + 1];
      domain.push(parseDomainName(buffer, pointer).domain);
      offset += 2;
      break;
    }
    offset++;
    domain.push(String.fromCharCode(...buffer.slice(offset, offset + len)));
    offset += len;
    len = buffer[offset];
  }
  return { domain: domain.join('.'), offset: offset + 1 };
}

直接调用该方法传入原始Uint8Array报文和域名起始偏移量(通常DNS报文前12字节是固定头部,域名从第12字节开始),就能正确解析出请求的完整域名。

内容的提问来源于stack exchange,提问作者ajaleksa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 20:39:03