跳到内容

如何将cURL命令转换为JavaScript fetch和Python requests|DevTools集成

分类:HTTP·API 开发
本文目前仅提供日文版本。我们正在进行翻译工作。

API 调试中的一项常见任务是「从 Chrome DevTools 中获取 cURL 命令并直接转换为代码」。本文解释了 <strong>cURL 选项结构</strong>、DevTools 的「Copy as cURL」功能的工作原理,以及到主要语言(JavaScript fetch / axios / Python requests / PHP cURL / Go net/http)的转换模式。使用文末介绍的 <a href="/ja/tools/curl/">cURL 转换工具</a>,您可以一次性复制粘贴进行转换。

为什么以cURL作为起点

在实现和调试 API 时,常见的工作流是首先「用 curl 验证它是否工作,然后再编写代码」。原因如下:

  • <strong>语言无关</strong>:curl 是在几乎任何环境中都可用的通用语言
  • <strong>从 DevTools 直接复制</strong>:在 Chrome / Firefox / Safari 的 Network 选项卡中右键单击请求 → Copy as cURL 可获得完整的可复现命令
  • <strong>确保可重现性</strong>:通过在错误报告或 Stack Overflow 问题中附加 curl 命令,其他人可以在任何环境下重现相同的请求

cURL主要选项

以下是必须掌握的 cURL 选项。

选项用途示例
-X / --requestHTTP 方法规范-X POST
-H / --header添加请求标头-H "Content-Type: application/json"
-d / --data请求正文-d '{"id":1}'
--data-raw不进行转义解释的原始数据--data-raw 'a=1&b=2'
-F / --formmultipart/form-data-F "file=@./a.png"
-u / --user基本身份验证-u user:pass
-b / --cookie发送 Cookie-b "session=abc"
-L / --location重定向追踪
-k / --insecure跳过 SSL 证书验证(仅开发时)
--compressedgzip 接受

从 DevTools 的 "Copy as cURL" 获得什么

在Chrome / Firefox / Edge中打开Network标签页,右键点击任何请求,您会看到菜单选项<strong>Copy → Copy as cURL</strong>。点击此选项会将完全再现的命令复制到剪贴板。

  • HTTP 方法和完整 URL
  • 发送的所有请求头(Authorization / User-Agent / Accept / Cookie 等)
  • 请求正文 (JSON / form-data / binary)
  • 通过 ANSI-C 引用 (<code>$'...'</code>) 进行转义

需要注意的是,Firefox的"Copy as cURL"使用<code>--data-raw</code>,而Chrome使用<code>--data-binary</code>等细微差异。转换工具需要能够识别这两种格式。

cURL 选项到 fetch 选项映射 cURL fetch -X POST method: 'POST' -H "Key: Val" headers: { Key: 'Val' } -d "body" body: 'body' -F file=@a.txt body: FormData --cookie credentials: 'include' -u user:pass Authorization: Basic
图1: 主要 cURL 选项与 fetch 选项的对应关系

转换为 JavaScript fetch

这是一个典型JSON POST转换示例。

# cURL
curl -X POST https://api.example.com/users \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"name":"Alice","email":"alice@example.com"}'
// JavaScript fetch
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN',
  },
  body: JSON.stringify({ name: 'Alice', email: 'alice@example.com' }),
})
  .then(r => r.json())
  .then(console.log);

axios版本

import axios from 'axios';

axios.post(
  'https://api.example.com/users',
  { name: 'Alice', email: 'alice@example.com' },
  { headers: { 'Authorization': 'Bearer YOUR_TOKEN' } }
).then(r => console.log(r.data));

转换为 Python requests

import requests

response = requests.post(
    'https://api.example.com/users',
    headers={
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN',
    },
    json={'name': 'Alice', 'email': 'alice@example.com'},
)
print(response.json())

关键是使用 <code>json=</code> 而不是 <code>data=</code>。指定 <code>json=</code> 时,requests 会自动将其序列化为 JSON,并自动设置 Content-Type。

转换为 PHP cURL

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/users');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer YOUR_TOKEN',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'name'  => 'Alice',
    'email' => 'alice@example.com',
]));

$response = curl_exec($ch);
curl_close($ch);
echo $response;

转换为 Go net/http

package main

import (
    "bytes"
    "io"
    "net/http"
)

func main() {
    body := bytes.NewReader([]byte(`{"name":"Alice","email":"alice@example.com"}`))
    req, _ := http.NewRequest("POST", "https://api.example.com/users", body)
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer YOUR_TOKEN")

    res, _ := http.DefaultClient.Do(req)
    defer res.Body.Close()
    data, _ := io.ReadAll(res.Body)
    println(string(data))
}

注意:严禁对令牌进行硬编码

将cURL命令转换为代码时,要小心不要<strong>直接将Authorization标头值(Bearer令牌或API密钥)写入代码并提交</strong>。

  • 通过环境变量读取生产令牌 (<code>process.env.API_TOKEN</code> / <code>os.environ['API_TOKEN']</code> / <code>getenv()</code>)
  • 提交前,用 <code>git diff</code> 确认没有混入秘密信息
  • 如果已提交,请立即使令牌失效(rotation),然后重写历史(git filter-repo)

DevLab cURL 转换工具

<a href="/ja/tools/curl/">DevLab 的 cURL ⇄ fetch / axios 转换工具</a>可以<strong>在浏览器中完成</strong>所有上述转换,只需一键点击。支持 13 种不同的目标格式:

  • JavaScript: fetch / axios / node-fetch / Node.js 标准 https
  • Python: requests / urllib
  • PHP: cURL / file_get_contents
  • Go: net/http
  • Rust: reqwest
  • wget / HTTPie / PowerShell Invoke-WebRequest

cURL选项支持<code>-X</code> <code>-H</code> <code>-d</code> <code>--data-raw</code> <code>--data-binary</code> <code>--data-urlencode</code> <code>-F</code> <code>-u</code> <code>-b</code> <code>-A</code> <code>-e</code> <code>-L</code> <code>-k</code> <code>-I</code>和ANSI-C quoting <code>$'...'</code>,并直接接受Chrome和Firefox的"Copy as cURL"输出。

总结

cURL是一种极其方便的与语言无关的HTTP再现通用语言,与DevTools相结合可以立即再现生产环境中的API请求。如果掌握本文所示的转换模式,可以从任何语言重现相同的行为。手动转换容易出现遗漏和错误(特别是Content-Type和引号转义),因此强烈建议使用自动化转换工具。