<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>デバッグ – AichiLog</title>
	<atom:link href="https://aichi.blog/tag/%E3%83%87%E3%83%90%E3%83%83%E3%82%B0/feed/" rel="self" type="application/rss+xml" />
	<link>https://aichi.blog</link>
	<description>学びて富み　富みて学ぶ</description>
	<lastBuildDate>Wed, 13 Aug 2025 14:01:42 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://aichi.blog/wp-content/uploads/2021/12/cropped-915AB649-D1E9-4810-9658-CB8CE1B605FD.JPEG-2-32x32.jpeg</url>
	<title>デバッグ – AichiLog</title>
	<link>https://aichi.blog</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>
<atom:link rel="hub" href="https://websubhub.com/hub"/>
<atom:link rel="self" href="https://aichi.blog/tag/%E3%83%87%E3%83%90%E3%83%83%E3%82%B0/feed/"/>
	<item>
		<title>Laravel で「CORS error」と表示された真犯人を突き止めるまで ―― “dump がヘッダーを確定させていた” という落とし穴と、その対処法</title>
		<link>https://aichi.blog/laravel-cors-error/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=laravel-cors-error</link>
		
		<dc:creator><![CDATA[愛知郎]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 03:53:46 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[CORS]]></category>
		<category><![CDATA[デバッグ]]></category>
		<guid isPermaLink="false">https://aichi.blog/laravel-cors-error/</guid>

					<description><![CDATA[<p>目次 症状 ―― CORS 設定を直しても消えない「CORS error」調査手順と気付き原因 ―― dump/dd/echo がヘッダーを先に送信していた修正方法 ―― サービス層の dump を Log::debug [&#8230;]</p>
<p>The post <a href="https://aichi.blog/laravel-cors-error/">Laravel で「CORS error」と表示された真犯人を突き止めるまで ―― “dump がヘッダーを確定させていた” という落とし穴と、その対処法</a> first appeared on <a href="https://aichi.blog">AichiLog</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>
  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">症状 ―― CORS 設定を直しても消えない「CORS error」</a></li><li><a href="#toc2" tabindex="0">調査手順と気付き</a></li><li><a href="#toc3" tabindex="0">原因 ―― dump/dd/echo がヘッダーを先に送信していた</a></li><li><a href="#toc4" tabindex="0">修正方法 ―― サービス層の dump を Log::debug に差し替える</a></li><li><a href="#toc5" tabindex="0">改善ポイントとベストプラクティス</a></li><li><a href="#toc6" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">症状 ―― CORS 設定を直しても消えない「CORS error」</span></h2>
</p>
<ul>
<li>フロント（Next.js）から <code>POST /api/entry</code> を呼ぶと DevTools に “CORS error” と表示される。</li>
<li>ネットワークタブには <strong>Status 200 / Size 0 B / Content-Type <code>text/html</code></strong> が並ぶ（JSON を返すはずが HTML になっている）。</li>
<li><code>config/cors.php</code> を編集したり、nginx で <code>add_header</code> を加えても改善しない。</li>
</ul>
<p>ここで「<strong>本当に CORS が原因なのか？</strong>」を疑うのがポイントです。</p>
<p><h2><span id="toc2">調査手順と気付き</span></h2>
</p>
<p>1. <strong>curl でエンドポイントを叩く</strong><br />
   まず <code>curl -i -X POST http://localhost/api/entry</code> を実行してみました。すると、ブラウザでは 200 ステータスが返ってきていたにもかかわらず、curl では <strong>500 Internal Server Error</strong> が返ってきました。<br />
   これにより、問題は <strong>CORS ではなくサーバーエラーであること</strong>が判明しました。</p>
<p>2. <strong>ブラウザのネットワークタブを再確認</strong><br />
   ブラウザのネットワークタブを見ると、レスポンスのコンテンツタイプが <strong><code>text/html</code></strong> になっていることに気付きました。本来 API レスポンスであれば <code>application/json</code> のはずです。これは <strong>何かが先に HTML を出力している可能性</strong> を強く示唆していました。</p>
<p>3. <strong>Postman で同じリクエストを送信</strong><br />
   Postman で同じリクエストを送信したところ、レスポンスボディには <strong><code>&lt;pre class="xdebug-var-dump"...&gt;</code> で始まる HTML</strong>（dump の内容）がそのまま返ってきました。これは <strong>dump の出力がそのまま HTTP レスポンスになっていること</strong>を示しています。</p>
<p>4. <strong><code>storage/logs/laravel.log</code> を tail</strong><br />
   <code>storage/logs/laravel.log</code> を tail したところ、外部 API 呼び出し前後でログが途切れていることがわかりました。これは <strong>途中で例外または予期せぬ出力が挟まっている可能性</strong> を示しています。</p>
<p>5. <strong>Xdebug でブレークポイントを設定</strong><br />
   サービス層のメソッド中で <code>dump($xml)</code> が実行されている箇所を発見しました。これは <strong>dump が HTML を即時出力しヘッダーを確定させていること</strong>を示しています。</p>
<p><h2><span id="toc3">原因 ―― dump/dd/echo がヘッダーを先に送信していた</span></h2>
</p>
<p><code>dump()</code> はデバッグ用関数で、呼ばれた瞬間にブラウザへ HTML を送り出します。</p>
<p>レスポンスヘッダーが <strong><code>Content-Type: text/html</code></strong> で確定してしまうため、その後に付与されるはずだった <code>Access-Control-Allow-Origin</code> などの CORS ヘッダーが入らなくなります。</p>
<p>結果、ブラウザからは <strong>「CORS エラー」としか見えません</strong>。</p>
<p><h2><span id="toc4">修正方法 ―― サービス層の dump を Log::debug に差し替える</span></h2>
</p>
<div class="hcb_wrap">
<pre class="prism line-numbers language-php" data-lang="php" data-show-lang="1"><code class="language-php" data-hcb-clip="0">// app/Services/HogeSyncService.php
class HogeSyncService
{
    public function sync(array $payload): array
    {
        $xml = $this-&gt;buildXml($payload);

        // ✗ NG： dump するとヘッダーが確定してしまう
        // dump($xml);

        // 〇 OK： Log に残せばブラウザへは何も送られない
        Log::debug('Hoge XML payload', ['xml' =&gt; $xml]);

        Http::post(config('hoge.endpoint'), $xml);

        return ['status' =&gt; 'ok'];
    }
}</code></pre>
<p><button class="hcb-clipboard" data-clipboard-target="[data-hcb-clip=&quot;0&quot;]" data-clipboard-action="copy" aria-label="コードをクリップボードにコピーする"></button></div>
<p><h2><span id="toc5">改善ポイントとベストプラクティス</span></h2>
</p>
<p>本番環境のコードには <code>dump</code>、<code>dd</code>、<code>echo</code> などのデバッグ用の出力を残さないようにしましょう。これらの関数はヘッダーが確定する前に呼び出されると、意図しないレスポンスヘッダーが送信されてしまう可能性があります。代わりに、ログ出力を使用するか、デバッグが完了したら完全に削除することをお勧めします。</p>
<p><h2><span id="toc6">まとめ</span></h2>
</p>
<p>1. ブラウザが出す “CORS error” は <strong>必ずしも CORS 設定の誤りを示すわけではない</strong>。<br />
2. Laravel/PHP では <strong>ヘッダー確定前に dump/echo を呼ぶ</strong> と CORS ヘッダーが付けられず、同じエラー表示になる。<br />
3. デバッグ出力は <strong>Log クラスへ切り替え（もしくは削除）</strong>、レスポンスは常に JSON で返すようにすれば解決。</p>
<p><strong>まずは curl と Postman とログを確認する</strong>。それだけで「CORS か、それ以外か」を簡単に切り分けられます。</p><p>The post <a href="https://aichi.blog/laravel-cors-error/">Laravel で「CORS error」と表示された真犯人を突き止めるまで ―― “dump がヘッダーを確定させていた” という落とし穴と、その対処法</a> first appeared on <a href="https://aichi.blog">AichiLog</a>.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
