跳到内容

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

分类:HTTP·API 开发

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

为什么以cURL作为起点

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

  • 语言无关:curl 是在几乎任何环境中都可用的通用语言
  • 从 DevTools 直接复制:在 Chrome / Firefox / Safari 的 Network 选项卡中右键单击请求 → Copy as cURL 可获得完整的可复现命令
  • 确保可重现性:通过在错误报告或 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标签页,右键点击任何请求,您会看到菜单选项Copy → Copy as cURL。点击此选项会将完全再现的命令复制到剪贴板。

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

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

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())

关键是使用 json= 而不是 data=。指定 json= 时,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命令转换为代码时,要小心不要直接将Authorization标头值(Bearer令牌或API密钥)写入代码并提交

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

DevLab cURL 转换工具

DevLab 的 cURL ⇄ fetch / axios 转换工具可以在浏览器中完成所有上述转换,只需一键点击。支持 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选项支持-X -H -d --data-raw --data-binary --data-urlencode -F -u -b -A -e -L -k -I和ANSI-C quoting $'...',并直接接受Chrome和Firefox的"Copy as cURL"输出。

总结

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

❓ 常见问题

DevTools 的 Copy as cURL 能直接拿来用吗?
用于复现请求很方便,但绝不要原样分享。Cookie 与 Authorization 头里带着你真实的会话,拿到的人可以以你的身份登录。贴到 issue 或聊天之前,务必删除认证相关的头或替换为占位符。
curl -d 与 fetch 的 body 是一回事吗?
内容可以完全一致,但 Content-Type 不同。未指定时 curl -d 会自动加上 application/x-www-form-urlencoded,而 fetch 什么都不加。以为在发 JSON 却忘了在 headers 里写 Content-Type: application/json,服务端看到的就是空 body——这是迁移时最常见的坑。
curl 的 -L 和 -k 在 fetch 里怎么写?
-L(跟随重定向)本就是 fetch 的默认行为,无需书写;只有想停止跟随时才加 redirect: 'manual'。浏览器 fetch 没有等价于 -k(跳过证书校验)的写法,因为浏览器不提供放弃 TLS 校验的手段。自签名证书请在 Node.js 一侧处理,或安装受信任的开发证书。