Chromeの検証ツール(DevTools)の「cURL としてコピー(Copy as cURL)」は、ブラウザが実際に送ったリクエストを、ヘッダー・Cookie・ボディ付きのcurlコマンドに変換する機能です。本記事では、取得の手順、コピーされるコマンドの中身(Chromiumのソースコードで確認)、Windowsでの形式の選び方、fetch・PowerShell・HARとの使い分け、認証情報を渡すときの注意、再現できないときの切り分けを順に扱います。メニュー名と挙動は2026年9月時点の安定版Chrome 154と、早期安定版として配信が始まった155に合わせています。
まとめ:形式の選び方と共有前に消す値
ターミナルで再実行するなら「cURL としてコピー」を使います。Windowsではメニューが「cURL(cmd)」と「cURL(bash)」の2つに分かれ、貼り付け先のシェルに合わせて選ばないと動きません。ブラウザのコンソールで値を変えて送り直すだけなら、Chrome 153で入った「フェッチとして編集して再送信」のほうが手数が少なく済みます。
コピーしたコマンドには、Cookie(-b)とauthorizationヘッダーがそのまま入ります。チャットやチケットに貼る前に、この2つに加えて独自ヘッダーのAPIキー、URLのクエリ、ボディ内のトークンを伏せてください。HARの「サニタイズ済み」が消すのは主にCookie・Set-Cookie・Authorizationヘッダーで、独自ヘッダーのAPIキー、URLのクエリ、ボディ、WebSocketのメッセージは残ります。
Copy as cURLの操作手順:Networkパネルで目的のリクエストを取る
DevToolsの起動と記録前の準備
DevToolsはF12、macOSならCmd+Option+I、またはページの右クリックから「検証」で開きます。Networkタブを開いた状態で操作しないと記録されないため、先にタブを開いてからページを再読み込みするか、対象の操作をやり直します。
- ログインや送信で画面が遷移する処理は、ツールバーの「ログを保持(Preserve log)」をオンにしておくと、遷移前のリクエストが消えません。
- API通信だけを見たいときは、フィルタの「Fetch、XHR」を選ぶと画像やCSSが一覧から外れます。
- 一覧から該当行を選び、Responseタブで期待したデータが返っているかを確かめてからコピーします。似た名前のエンドポイントが複数並ぶ画面では、ここで取り違えやすいためです。
右クリックメニューからのコピー
対象の行を右クリックし、「コピー」→「cURL としてコピー」を選びます。Windows版のChromeではこの項目が「cURL(cmd)としてコピー」と「cURL(bash)としてコピー」の2つに分かれます(Chromiumのソースで、Windowsのときだけ2項目を出す分岐になっています)。同じサブメニューの下段にある「cURL としてすべてコピー」などの「…としてすべてコピー」は、一覧に表示中の全リクエストをまとめて書き出します。フィルタを掛けているときは表記が「表示されているものをすべて…」に変わり、絞り込んだ分だけが対象です。
コピーできないのはblob:のURLへのリクエストで、メニューがグレーアウトします。URLのスキームもhttp・https・ws・wss・data以外は変換されません。
コピーされるcurlコマンドの中身(Chromiumのソースで確認)
次のPOSTリクエストをmacOS・Linux用の形式でコピーした場合の出力例です。生成ロジック(devtools-frontendのNetworkLogView.ts内のgenerateCurlCommand)を移植して生成し、curl 8.7.1でローカルのエコーサーバーへ送って、Cookie・ヘッダー・ボディがそのまま届くことを確かめました。
curl --url 'https://api.example.com/api/orders?page=2' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJhbGciOi...' \
-H 'content-type: application/json' \
-b 'session=abc123; theme=dark' \
-H 'origin: https://app.example.com' \
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/155.0.0.0' \
--data-raw '{"item":"A-100","qty":2}'
読み方の要点は次のとおりです。
| 要素 | 出力のされ方 | 導入された版 |
|---|---|---|
| URL | --urlオプションで渡す |
Chrome 151 |
| Cookie | 値に=があれば-b |
Chrome 133 |
| Accept-Encoding | 出力しない | – |
--compressed |
付けない | 2023年12月に削除 |
| Host・:authority等 | 出力しない(URLから再生成) | – |
| ボディ | --data-raw(Content-Lengthは除外) |
– |
| メソッド | 推定と違うときだけ-X |
– |
| 値が空のヘッダー | -H 'name;' |
2022年8月の変更 |
| 安全でない(Insecure判定の)通信 | 末尾に--insecure |
– |
版は、各変更のコミットがChromeのどのリリースブランチに含まれるかで特定しました。実務で効くのは次の3点です。
- レスポンスは圧縮されずに返る:Accept-Encodingを落とすので、サーバーは通常、非圧縮で応答します。以前は末尾に
--compressedが付いていましたが、Windowsのcurlが既定でこのオプションに対応していないことを理由に、2023年12月に外されました。 - メソッドは推定される:ボディがあればPOST、なければGETとみなし、実際のメソッドが違う場合(PUT・DELETE等)だけ
-Xが付きます。ボディ付きのPOSTに-Xが無いのは正常です。 --data-rawは@をファイル指定として扱わない:--dataと違い、@で始まる値もそのまま送ります。このオプションはcurl 7.43.0で追加されたため、それより古いcurlでは「unknown option」で止まります。
cmd・bash・PowerShell・fetchの違いと選び方
同じ「コピー」メニューに並ぶ形式は、実行する場所で選びます。
| メニュー名 | 実行場所 | 行継続 | Cookieの渡し方 |
|---|---|---|---|
| cURL としてコピー | macOS・Linuxのシェル | \ |
-b |
| cURL(bash)としてコピー | Git Bash・WSL | \ |
-b |
| cURL(cmd)としてコピー | コマンドプロンプト | ^ |
-b |
| PowerShell としてコピー | PowerShell 5.1・7 | バッククォート | WebRequestSession |
| fetch としてコピー | 対象ページのコンソール | – | ブラウザ任せ |
| fetch(Node.js)としてコピー | Node.js | – | cookieヘッダー |
WindowsでコピーしたcURLが動かない原因
多くは、形式と貼り付け先のシェルが合っていないことが原因です。cmd版は^"で値を囲み、行末の^で改行をつなぎます。同じリクエストをcmd版で出すと次のようになります(ヘッダーは一部省略)。
curl --url ^"https://api.example.com/api/orders?page=2^" ^
-H ^"accept: application/json^" ^
-b ^"session=abc123; theme=dark^" ^
--data-raw ^"^{^\^"item^\^":^\^"A-100^\^",^\^"qty^\^":2^}^"
これはコマンドプロンプト専用で、PowerShellに貼ると^が解釈されず失敗します。逆にbash版をコマンドプロンプトに貼ると、シングルクォートと\が解釈されません。もう一つ見落としやすいのがWindows PowerShell 5.1で、curlがInvoke-WebRequestのエイリアスになっています。そのため-Hや-bを渡すと引数エラーになります。PowerShellからcurlを使うならcurl.exeと拡張子まで書くか、PowerShell 7を使ってください(7.6のInvoke-WebRequestのエイリアスはiwrだけです)。Windows標準のcurl.exeは、2017年12月のInsider Build 17063から同梱されています。
PowerShellで直接動かしたいなら、最初から「PowerShell としてコピー」を選ぶのが確実です。生成コードはUser-AgentとCookieを-Headersに入れず、WebRequestSessionを作ってその中に入れ、-WebSessionで渡します(PowerShell 7.6では-Headersに直接書いても両方送れます)。PowerShell 7.6.6で実行し、Cookieとメソッドがサーバーに届くことを確認しました。
fetchとfetch(Node.js)の違い
ブラウザ用の「fetch としてコピー」は、ブラウザが自分で付けるヘッダー(Cookie・User-Agentなどの禁止ヘッダー)を出力しません。Cookieはcredentials: "include"を指定してブラウザに付けさせる形になるため、対象サイトのタブのコンソールで実行したときにだけ同じ条件になります。別オリジンのタブで実行すると、サーバーがCORSで許可していない限りブロックされます。
「fetch(Node.js)としてコピー」はサーバー側で動かす前提で、ブラウザ任せにできないCookieとRefererを通常のヘッダーとして書き出し、modeを外します。Node.jsのスクリプトに貼るとログイン状態ごと再現できる反面、Cookieの値がソースコードに残るので、コミットしないよう扱いに注意してください。
フェッチとして編集して再送信:コピーせずに値を変えて送り直す
Chrome 153から、リクエストの右クリックメニューに「フェッチとして編集して再送信(Edit and resend as fetch)」が加わりました。選ぶとDevToolsの下部にコンソールが開き、await fetch(...)の形のコードが入力欄に入った状態になります。パラメータを書き換えてEnterを押せば、その場で送り直せます。「IDだけ変えて試す」「ヘッダーを1つ外して挙動を見る」程度なら、ターミナルに移るより速く済みます。
通常のfetchコピーと違い、CookieやOriginなどブラウザが自分で付ける禁止ヘッダーも削除されず、「ブラウザが Cookie 格納場所から管理します」(英語UIでは「Browser manages this from the cookie jar」)のような理由付きでコメントアウトされて残ります。コードの先頭には元のリクエストを発行した実行コンテキスト(topや、iframe・Workerの名前)がコメントで示されます。iframeやWorkerから出たリクエストなら、コンソール上部のコンテキスト選択をそれに合わせてから送ります。同じ場所にある「再送信(Resend)」は、値を変えずにそのまま送り直す機能です。ただし、両方ともブラウザ内で完結するため、CIやスクリプトに持ち出して繰り返し実行する用途には、これまでどおりcURLのコピーを使います。
認証情報を含むコマンドとHARの安全な共有
共有前に伏せる値
コピーしたコマンドをそのまま貼れば、受け取った人は誰でもあなたのセッションで同じ操作ができます。バグ報告やチャットに貼る前に、次の値を<REDACTED>などに置き換えます。
-bの値(セッションCookie全体)authorizationヘッダー(Bearerトークン、Basic認証)x-api-keyやx-csrf-tokenなど、サービス独自のヘッダー- URLのクエリに入ったトークンや署名(
?token=、&signature=など) --data-rawのボディに含まれるパスワード・個人情報
誤って公開の場所に貼った場合は、コマンドを消すだけでなく、ログアウトやトークンの再発行でその値を無効にしてください。Cookieやトークンは有効期限まで使えるため、削除しても手元に写した人は使えてしまいます。
HAR(サニタイズ済み)が消すのはCookieとAuthorizationだけ
Chrome 130以降、HARの書き出しとコピーは既定でサニタイズされます。ただしChromiumのHAR生成コード(models/har/Log.ts)が除去するのは、リクエストのAuthorizationとCookie、レスポンスのSet-Cookie、Cookieの一覧、Server-Sent Eventsのメッセージ本文だけです。独自ヘッダーのAPIキー、URLのクエリ、リクエストとレスポンスのボディ、WebSocketで送受信したメッセージはそのまま残ります。ログインAPIのレスポンスにアクセストークンが入る構成なら、サニタイズ済みのHARでもトークンが渡ってしまいます。
Cookie込みのHARが必要なときは、DevToolsの設定のNetworkで「センシティブ データを含む HAR の生成を許可する」をオンにすると、「センシティブ データを含む」項目がメニューに現れます。サポート窓口から求められた場合でも、渡した後にログアウトしてセッションを切っておくのが安全です。
コピーしたcURLで再現できないときの切り分け
まずHTTPのステータスで分けます。-iを付けて実行するとレスポンスヘッダーごと表示されます。
- 401・403:まず疑うのはCookieやトークンの期限切れです。ブラウザで同じ操作をやり直し、コピーし直して比べます。
- 403でCSRFエラーの文言が返る:フォームやヘッダーのCSRFトークンが使い捨て、またはセッションと対になっています。直前にトークンを取り直す手順が要ります。仕組みはCSRFトークンの仕組みとSPAでの実装で解説しています。
- ブラウザ用fetchでだけ失敗する:多くは、別オリジンのページのコンソールで実行したことによるCORSです。対象サイトのタブで実行し直します。
- ファイルアップロードが再現しない:
--data-rawにファイルの中身が入っているかを確かめ、欠けていれば-F 'file=@./sample.png'の形で組み直します。 - ボット対策のあるサイトで403:CookieとUser-Agentが同じでも、TLSやHTTP/2の特徴で弾かれることがあります。コマンド側で合わせる手段はほぼ無いため、APIの正式な利用手段を確認します。
HTTPの応答が返らず、curl自体が終了コードを出して止まる場合は、コードで原因を絞ります。
| 終了コード | 意味 | 最初に見る所 |
|---|---|---|
| 6 | ホスト名を解決できない | 社内DNS・VPN・hosts |
| 7 | 接続できない | プロキシ設定・ポート |
| 28 | タイムアウト | ネットワーク経路・サーバー負荷 |
| 35 | TLSハンドシェイク失敗 | TLSバージョン・中間装置 |
| 60 | 証明書を検証できない | 社内CA・プロキシの証明書 |
各コードの詳しい意味はHTTPステータスコードとcurlエラーコードの一覧にまとめています。社内プロキシのある環境では、ブラウザがOSのプロキシ設定と証明書ストアを使う一方、curlはそれらを参照しない構成があり、ブラウザは通るのにcurlだけ7や60で落ちることがあります。その場合は-xでプロキシを指定し、社内CAの証明書を--cacertで渡します。
Postmanへの取り込みとバグ報告での使い方
コピーしたcURLは、Postmanの「Import」画面の入力欄に貼るだけでリクエストとして取り込めます。ヘッダー・Cookie・ボディが分解されて入るので、値を変えながら試したり、コレクションに保存してテストに組み込んだりできます。取り込んだ後の自動テストやCIでの実行はPostmanでのAPIテスト自動化とNewmanでのCI組み込みで扱っています。レスポンスのJSONから値を抜き出して確認するなら、curlの出力をjqコマンドにパイプすると見やすくなります。
バグ報告では、画面の症状とともにマスク済みのcURLを添えると、受け手が同じリクエストを1行で再現できます。ただしCookieを伏せたコマンドは受け手の手元では認証を通りません。「自分のアカウントでログインし、該当行をコピーし直して実行する」手順を併記しておくと、やり取りの往復が減ります。
DevToolsの操作そのものをAIエージェントに任せたい場合は、Chrome DevTools MCPの導入手順で、エージェントからネットワークリクエストを読み取る方法を解説しています。
Copy as cURLに関するよくある質問
Copy as cURLはどこにありますか?
DevToolsのNetworkタブで対象のリクエストを右クリックし、「コピー」のサブメニューを開いた中にあります。日本語表示では「cURL としてコピー」、Windowsでは「cURL(cmd)としてコピー」と「cURL(bash)としてコピー」の2つです。
WindowsでコピーしたcURLが動かないのはなぜですか?
形式と貼り付け先のシェルが合っていないのが主な原因です。cmd版はコマンドプロンプト専用、bash版はGit BashやWSL用です。Windows PowerShell 5.1ではcurlがInvoke-WebRequestのエイリアスなので、curl.exeと書くか「PowerShell としてコピー」を使います。
Copy as cURLとCopy as fetchはどちらを使うべきですか?
ターミナル・Postman・CIで繰り返し実行するならcURLです。対象ページのコンソールで少し値を変えて送り直すだけなら、fetchのコピーか、Chrome 153以降の「フェッチとして編集して再送信」が手早く済みます。
HAR(サニタイズ済み)なら社外に渡しても安全ですか?
安全とは言い切れません。除去されるのはCookie・Set-Cookie・Authorizationヘッダーだけで、独自ヘッダーのAPIキー、URLのクエリ、リクエストとレスポンスのボディは残ります。渡す前にテキストエディタで検索し、トークンが残っていないか確認してください。
コピーしたcURLのレスポンスが文字化けしたりバイナリになったりしませんか?
現在のChromeはAccept-Encodingヘッダーを出力しないため、通常は非圧縮のテキストで返ります。日本語が化ける場合は、ターミナルの文字コード設定か、レスポンスのContent-Typeのcharsetを確認します。