YamlBox

网络和编码 · 5 分钟阅读

cURL to fetch:将请求从终端移动到浏览器

用于获取转换的 cURL 是从 API 的文档到工作前端代码的通常途径:理解 API 的最快方法是从其文档复制 cURL 命令,最快的传送方法是 `fetch`。它们之间的转换大部分是机械的——标志映射到选项对象上——但是有两件事经常会破坏转换:主体编码和终端中没有等效项的浏览器安全模型。

已更新

旗帜如何映射

  • `-X POST`→`method: "POST"`(或从`-d`推导方法)。
  • `-H "Content-Type: application/json"` → `headers` 中的条目。
  • `-d '{"a":1}'` → `body: JSON.stringify(...)`;除非您另有说明,否则 cURL 会以表单编码的方式发送它。
  • `--data-binary @file` → `Blob`、`FormData` 或 `ArrayBuffer` 实体而不是字符串。
  • `-u user:pass`→从`user:pass`的base64构建的`Authorization: Basic …`标头。
  • `-F name=@file`→`FormData`加`File`,这是文件上传的表达方式。
                await fetch('https://api.example.com/v1/orders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + token,
  },
  body: JSON.stringify({ sku: 'YB-1', qty: 2 }),
});
              

CORS:cURL 从未考虑过的部分

cURL 在浏览器的安全模型之外运行,因此它可以调用任何应答的主机。页面中的 `fetch` 受 CORS 绑定:服务器必须允许您的来源,对于简单请求之外的任何内容,它还必须正确回答预检 `OPTIONS`。正是由于这个原因,在终端中完美运行的转换后的命令可能会在浏览器中失败,并出现不透明的网络错误 - 并且请求中的任何标头编辑都无法修复它,因为权限必须来自服务器。

如果提取失败并显示 CORS 消息,则修复会在 API 或您的代理上进行,而不是在 JavaScript 中进行。切勿通过在客户端代码中放置 API 键来“避免”该问题来解决此问题。

凭证、重定向和流式传输

还有两个行为与终端不同。除非您传递 `credentials: "include"`,否则不会发送 Cookie,并且服务器必须使用明确的来源而不是通配符进行响应。默认情况下,重定向后跟 `redirect: "follow"`,但重定向会丢失跨源的 `Authorization` 标头,除非服务器处理它,这就是为什么经过身份验证的调用通常需要 `redirect: "manual"` 并特意遵循。流响应从 `response.body` 读取为 `ReadableStream`,其中 cURL 只是在接收时进行打印。

fetch 还是 axios?

`fetch` 内置,可在现代环境中随处使用; axios 增加了便利性 — 自动 JSON 解析、拦截器、非 2xx 响应的可读错误、在旧运行时上传进度。转换后的 cURL 命令是以下任一方面的可靠起点:将生成的选项粘贴到 axios 调用中,并且标头和正文保持不变。

转换不泄漏

从真实会话复制的 cURL 命令通常携带实时承载令牌、API密钥或会话 cookie。在浏览器中运行的转换会将这些凭据保留在您的计算机上,这是处理并非您自己键入的请求的唯一明智的方法。

cURL 来获取 — 常见问题

为什么我转换后的提取请求失败并出现 CORS 错误?

因为浏览器强制执行同源策略,而 cURL 则不强制执行。 API 必须发送适当的`Access-Control-Allow-Origin` 标头并处理预检请求。当第三方 API 不允许浏览器来源时,通过您自己的后端进行代理是标准修复方法。

如何使用 fetch 而不是 JSON 发送表单数据?

使用 `FormData` 对象作为主体,并让浏览器设置多部分边界 - 不要自己设置 `Content-Type`,因为该值包含浏览器生成的边界标记。这还包括从 `-F` 标志上传的文件。

fetch默认发送cookie吗?

不会。当应用`credentials: "same-origin"`时,同源请求包含cookie,但跨源调用需要`credentials: "include"`,并且服务器必须使用显式来源而不是通配符进行响应,以便读取响应。

这篇文章中提到的工具

浏览 19 工具的完整列表

更多文章可供阅读

所有19帖子→