Skip to content

How to Convert cURL Commands to JavaScript fetch and Python requests|DevTools Integration

Category: HTTP / API Development
This article is currently available in Japanese only. We are working on translations.

A common task in API debugging is "taking a cURL command from Chrome DevTools and converting it directly to code." This article explains <strong>cURL option structure</strong>, how DevTools' "Copy as cURL" feature works, and conversion patterns to major languages (JavaScript fetch / axios / Python requests / PHP cURL / Go net/http). Using the <a href="/ja/tools/curl/">cURL conversion tool</a> introduced at the end, you can convert these with a single copy-paste.

Why start with cURL

When implementing and debugging APIs, the common workflow is to first "verify it works with curl before writing code." The reasons are as follows:

  • <strong>Language-agnostic</strong>: curl is a universal language available in nearly any environment
  • <strong>Copy directly from DevTools</strong>: In the Network tab of Chrome / Firefox / Safari, right-click a request → Copy as cURL to get a complete reproducible command
  • <strong>Reproducibility assurance</strong>: By attaching a curl command to bug reports or Stack Overflow questions, others can reproduce the exact same request regardless of environment

cURL Major Options

The essential cURL options are listed below.

OptionsUse caseExample
-X / --requestHTTP Method Specification-X POST
-H / --headerAdd Request Header-H "Content-Type: application/json"
-d / --dataRequest Body-d '{"id":1}'
--data-rawRaw data without escape interpretation--data-raw 'a=1&b=2'
-F / --formmultipart/form-data-F "file=@./a.png"
-u / --userBasic Authentication-u user:pass
-b / --cookieSend Cookie-b "session=abc"
-L / --locationRedirect Following
-k / --insecureSkip SSL certificate verification (development only)
--compressedgzip Accept

What You Get from DevTools' "Copy as cURL"

Open the Network tab in Chrome / Firefox / Edge, right-click on any request, and you'll see a menu option <strong>Copy → Copy as cURL</strong>. Clicking this copies a fully reproduced command to your clipboard.

  • HTTP Method and Full URL
  • All request headers sent (Authorization / User-Agent / Accept / Cookie, etc.)
  • Request Body (JSON / form-data / binary)
  • Escape via ANSI-C quoting (<code>$'...'</code>)

One point to note is that Firefox's "Copy as cURL" uses <code>--data-raw</code>, while Chrome uses <code>--data-binary</code>, among other subtle differences. Your conversion tool implementation needs to recognize both formats.

cURL options to fetch options mapping 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
Fig 1: Mapping between major cURL options and fetch options

Convert to JavaScript fetch

Here is an example of a typical JSON POST conversion.

# 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 Version

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

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

The key is to use <code>json=</code> instead of <code>data=</code>. When you specify <code>json=</code>, requests automatically serializes to JSON and sets the Content-Type automatically.

Convert to 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;

Conversion to 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))
}

Warning: Hardcoding tokens is strictly prohibited

When converting cURL commands to code, be careful not to <strong>write Authorization header values (Bearer tokens or API Keys) directly in the code and commit them</strong>.

  • Read production tokens via environment variables (<code>process.env.API_TOKEN</code> / <code>os.environ['API_TOKEN']</code> / <code>getenv()</code>)
  • Before committing, verify with <code>git diff</code> that no secret information is included
  • If already committed, immediately invalidate the token (rotation) and rewrite history (git filter-repo)

DevLab cURL Conversion Tool

<a href="/ja/tools/curl/">DevLab's cURL ⇄ fetch / axios conversion tool</a> executes all the above conversions with a single click, <strong>entirely in your browser</strong>. Supports 13 different target formats:

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

cURL options support <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> and ANSI-C quoting <code>$'...'</code>, and accept Chrome and Firefox "Copy as cURL" output directly.

Summary

cURL is extremely convenient as a language-independent HTTP reproduction common language, and when combined with DevTools, it allows you to immediately reproduce API requests in production. If you master the conversion patterns shown in this article, you can reproduce the same behavior from any language. Manual conversion is prone to errors and omissions (especially with Content-Type and quote escaping), so I strongly recommend using automated conversion tools.