フォームとiframeとCORSの関係

Webサイトに問い合わせフォームを設置しようとすると、意外なところでCORS(クロスオリジン制限)という壁にぶつかります。
今回は、実際にCanvaで作ったサイトにフォームを埋め込みながら、この問題をどのように理解し、解決していったかを記録します。

関連記事

1. 最初に考えた「自作フォーム」構想

最初は、レンタルサーバーにシンプルなHTMLフォームを置いて、PHPでメール送信する仕組みを作ろうとしました。入力欄は名前・メールアドレス・問い合わせ内容の3つ。送信ボタンを押すと、会社の受付メールに届く、という基本的な流れです。

HTMLとPHPの組み合わせなら昔から定番ですし、「これならすぐできる」と思っていました。
ところが、Canvaで作ったWebサイトの中にそのフォームを直接埋め込もうとしたところ、思わぬ疑問が浮かびます。

「iframeで外部のフォームを読み込むと、CORSに引っかからないのだろうか?」

2. CORSに引っかかるフォームとそうでないフォーム

CORS(Cross-Origin Resource Sharing)は、ブラウザが“異なるドメイン間の通信”を制限する仕組みです。
たとえばJavaScriptでfetch()を使って他のサーバーにデータを送ると、相手側が明示的に許可していない限り、ブラウザがブロックします。

一方、HTMLの<form>タグによる送信や、<iframe>で外部ページを表示する行為は、CORSの対象外です。ブラウザはそれらを「ユーザー操作による正規の画面遷移や表示」として扱うからです。

つまり、JavaScriptでAPIを直接呼ぶ問い合わせフォームを作るとCORSに制限されますが、サーバー側で完結するフォーム(PHPなどでPOSTを処理する)は制限されません。

JavaScriptが“裏で通信”するのがCORSの対象。
フォームやiframeは“表で通信”している扱い。

3. 実際にiframeで埋め込んでみた

Canvaの「埋め込み」機能を使って、サーバー上のフォームページを読み込むには、

<iframe src="https://example.com/contact.html"
 width="100%" height="600" frameborder="0"></iframe>
Code language: HTML, XML (xml)

すると、フォームがそのままCanvaサイト内に表示されます。
HTTPS同士であれば警告も出ません。
送信ボタンを押すと、サーバー側のPHPが処理し、メールが問題なく届きました。

JavaScriptで送信していたらCORSヘッダーを設定する必要がありましたが、この方法では不要。
Canva側はただの“外部表示”なので、フォームの処理はサーバー側だけで完結します。

4. iframeは画像に近い存在

試していて感じたのは、iframeは画像や動画の埋め込みに近いということです。
<img>が外部の画像を読み込むように、<iframe>は外部のHTMLをそのまま読み込むだけ。
CORSは“JavaScriptによるデータの取得”を制限する仕組みなので、単なる表示は問題になりません。

ただし、注意点もあります。
iframe内の内容を親ページのJavaScriptで操作しようとすると、Same-Origin Policy(同一オリジン制限)でブロックされます。
表示は自由でも、内部のDOMにアクセスするのは不可です。

iframeは表示は自由。
でも中を触ろうとすると、すぐに『ここは他人の家です』と怒られる。

5. まとめ:フォームは“どこで完結させるか”が鍵

今回の検証で理解したのは、「CORSの問題は、どこでデータを送信し、どこで処理するか」で決まるということです。

  • 同一サーバー内でフォーム送信 → 問題なし
  • iframeで外部フォームを読み込む → 表示はOK、処理は外部で完結
  • フロントのJSが別ドメインに送信 → CORSが必要

結局、最も安定するのは「フォームと送信処理を同じサーバーに置き、Canva側はiframeで見せるだけ」という構成でした。CORS設定も不要で、動作も軽い。