まずはリバースプロキシを使うことになった経緯から。
開発中のWebサービスにチャット機能を実装するにあたり、Socket.IOを使う必要がありました。
しかし、セキュリティが強い(制限が強い)ネットワークからhttps://example.com:8080
のようにオリジン直指定でSocket.IOサーバーへ接続しようとすると接続が弾かれるため、それを回避するためにリバースプロキシを使うことにしました。
やり方をググって、nginxの設定ファイルに変更を加えたものの、No 'Access-Control-Allow-Origin' header is present on the requested resource
というCORSエラー連発で、Access-Control-Allow-Originヘッダーを追加しているのにも関わらず中々うまくいかず苦戦していたのですが、やっと解決法が判明し、リバースプロキシもうまく機能するようになったのでポイントも交えながら手順を解説していきます。
(何気に技術系の記事書くの初めてなので温かい目で読んでくれると嬉しいです)
前提条件
- Socket.IOサーバーは8080番ポートでListenしている
- Socket.IOクライアントで、
https://example.com
を接続先として指定するが、既にこのドメインは自分の別のサイトで使用中である(ブラウザーからexample.comにアクセスすると自分が運用中の別のサイトに繋がる)。つまり、リバースプロキシ用のサブドメインを設定したり、わざわざSSL証明書取ってきたり設定ファイル新しく作ったりするのが面倒なので、既存サイトのドメインを使いつつ、その設定ファイルにちょっと手を加えるだけでリバースプロキシを使えるようにする、という横着なやつですね!←
nginxの設定ファイルを書き換える
自分はnginxのバーチャルホスト機能で、複数サイトを同時に運用しているので
で設定ファイルを編集していきます。設定ファイルは環境によって異なりますので、ご自身に合ったファイルを編集してください。
関係ない部分は端折ってますが、20行目~34行目が今回追加した部分です。
serverディレクティブの中にlocationディレクティブを追加していますが、ポイント1つ目が、リクエストURIのパスに「/socket.io/」を指定することです。
というのも、Socket.IOクライアントはhttps://example.com/socket.io/?EIO=4&transport=polling
というURLに接続しに行くので、「/socket.io/」というパスに対しての導線を張ってやらないといけないというわけなんですね。
普通Socket.IOサーバーのURLを指定するとき、https://example.com:8080
のように「/socket.io/」の部分は端折るので、locationディレクティブのリクエストURIに「ws」とか自分の好きな文字列を設定しておいて、クライアントからhttps://example.com/ws/
のように指定して接続するイメージだったのが違いました。この誤解が原因で結構時間を食ってしまいました。
その下のproxy_set_headerの記述は公式ドキュメントからの引用です。
proxy_passにはnginxから見た場合のSocket.IOサーバーのURLを指定しましょう。今回は、どちらも同一サーバー上で動かしているのでアドレスはグローバルIPなどではなくlocalhostになります。
更に下のproxy_set_headerはCORS関連の記述になります。開発の都合上、Access-Control-Allow-Originを*にしていますが、セキュリティのためにもオリジンは限定しておいたほうが良いでしょう。
設定ファイルの編集・保存が終了したら、
で一旦nginxを止めて、
設定ファイルに記述ミスなどが起きていないことを確認し、
再度nginxを立ち上げます。
クライアントから接続先を指定する
サーバー側の設定が完了したので、クライアントのソースコードから接続先を指定します。
socket.io-clientをContextAPIで使っているので若干関係ない記述も入っていますが、4行目でアドレスを指定していますね。ここでポイント2つ目なのですが、接続先URLには「/socket.io/」は含めません。
さっき/socket.io/に対する導線を張ったので接続先URLに入れたくなりますが、入れません。
この辺りがややこしいですね。
接続確認してみよう
サーバー、クライアントともに設定できたところで、正常に接続できるか確認してみましょう。
意外と設定だけで満足して、肝心のSocket.IOサーバーを起動し忘れてることがよくあるので忘れずに!w

こんな感じで、Socket.IOのオブジェクトを見てみるとconnectedがtrueになっていることが確認できました。
この記事は 2025/08/12 02:38:41 にビルドされました