Deno 的 Node 兼容踩坑

TL;DR: Node 兼容层的 http.request() 曾经不支持 headers,被我水了个 PR

试用 import from npm:

用 Deno 写飞书机器人的时候,随手试了一下通过 npm: 调用飞书的 Node.js SDK。

看上去真的能用:

(直呼好用,连 TypeScript 类型定义都有了~)

踩坑

但是调用接口时,飞书服务端会返回这样的报错:

{
  "code": 99991661,
  "msg": "Need a token",
  "error": { "subcode": 20109008, "log_id": "***" }
}

飞书开放平台文档中对这个错误码的描述:

请求需要使用token认证;请检查请求Header中是否填了正确的Authorization,注意token值前不要漏了 "Bearer "。详情可参考 API访问凭证概述

我:???明明是按照 readme 的示例写的。

于是看了 SDK 的源码确认了 SDK 会自动设置这个 toekn header。因为SDK 通过 axios 发送请求,所以再看看 axios 源码,调用的是 Node 的 http.request()

最后发现了问题的原因在 deno_std/node (Deno 标准库中实现的 Node.js 兼容层)的 http 实现,它的很多部分还是待实现的状态。但是,好家伙,调用底层 fetch 的时候根本就不会传 headers……

填坑

于是把 headers 补上,刚好能用了。

再水个 PR: https://github.com/denoland/deno_std/pull/2898

Workaround

Deno v1.28.2 已包含此修复。

官方发版之前,只能先通过 import_map 暂时替换 deno_std 实现:

import_map.json

{
  "imports": {
    "https://deno.land/std@0.164.0/":
      "https://raw.githubusercontent.com/lideming/deno_std/main/"
  }
}

启动时添加 --import-map 参数

deno run --import-map import_map.json ...