콘텐츠로 건너뛰기

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 / --userBasic 인증-u user:pass
-b / --cookieCookie 전송-b "session=abc"
-L / --location리다이렉트 추적
-k / --insecureSSL 증명서 검증 건너뛰기 (개발 시에만)
--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 quoting (<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>data=</code> 대신 <code>json=</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 명령을 코드로 변환할 때 Authorization 헤더 값(Bearer 토큰이나 API 키)을 <strong>그대로 코드에 작성해서 커밋하지 않도록</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이나 따옴표 이스케이프)이 발생하기 쉬우므로 자동화된 변환 도구 사용을 강력히 권장합니다.