要約
WindowsでVite(v5)の開発サーバを起動中、Vivaldiのみ接続可でChrome/Edge/BraveはERR_CONNECTION_REFUSEDとなる事象を解析。
Get-NetTCPConnectionで::1待受を確認し、OSレベルではhttp://[::1]:5173/へ疎通可。
根因はViteがIPv6ループバックのみでLISTENし、Chromium側のlocalhost解決・プロキシ・HTTPS強制(HSTS: HTTPSを強制する仕組み)等の差分と噛み合った点。
対処はViteのserver.hostとserver.hmr.hostを127.0.0.1に固定し、.viteキャッシュ削除後に再起動。必要に応じブラウザのプロキシ例外/HSTSを整理することで全ブラウザで安定接続を得られる。
目次
-
はじめに
- 前提と範囲 / ゴール
-
症状と観測事実
- OSレベル疎通 vs ブラウザの拒否
- LISTENアドレスの確認
-
根本原因の整理
- Viteの
localhost解決とIPv6(::1)待受 - ブラウザ側ポリシー(プロキシ/HSTS/HTTPS強制)
- Viteの
-
恒久対処(推奨設定:IPv4 & HMRのIPv4固定)
-
代替案(ネットワーク公開や両対応時の注意)
-
迅速な診断フロー(Windows/PowerShell)
-
ブラウザ/OS側の整備ポイント
-
比較と選定理由(表)
-
ベストプラクティス
-
まとめと次の一歩
-
参考文献/出典
-
プラットフォーム別メタ
-
SNS告知文
はじめに
要点: localhostは環境で意味が揺れます。Vite側・ブラウザ側の両輪で整えるのが最短。
前提と範囲 / ゴール
- 対象読者:フロントエンド開発者 / IT管理者
- 検証環境:Windows(PowerShell 7.5.3)、Vite v5.4.20 + React、Chromium系(Chrome/Edge/Brave/Vivaldi)
- ゴール:Vite開発サーバへ全ブラウザから安定接続できる状態に戻す。再現可能な診断と恒久対処を残す。
- 除外:Docker/WSL2越し公開や社外LAN公開は最小限の注意点のみ。
症状と観測事実
要点: OSからは通るのに、ブラウザが拒否するなら「待受アドレス×ブラウザ層のポリシー差」を疑う。
-
症状:
http://localhost:5173はVivaldiのみOK、Chrome/Edge/BraveはERR_CONNECTION_REFUSED。 -
OSレベル疎通(事実確認):
Test-NetConnection 127.0.0.1 -Port 5173 Test-NetConnection ::1 -Port 5173 curl -v http://127.0.0.1:5173/ curl -v http://[::1]:5173/ここで
::1が成功するなら、サーバは落ちていない。 -
LISTEN確認:
Get-NetTCPConnection -State Listen -LocalPort 5173 | ft LocalAddress,LocalPort,OwningProcessLocalAddress = ::1→ IPv6ループバック待受のみであることを示す。
根本原因の整理
要点: Viteの待受が::1のみ + ブラウザのlocalhost処理差(DNS解決順序/プロキシ/HSTS等)。
-
Viteの
server.host既定は"localhost"。環境によってはlocalhost解決結果と実際のLISTENアドレスがズレます。Vite公式は、NodeのDNS解決順序の影響で表示URLと実LISTENの不一致が起こり得る旨に言及(Server Options参照)。(Vite Docs: https://vite.dev/config/server-options#server-host ) -
Node.js側では
dns.setDefaultResultOrder()/--dns-result-orderでIPv4/IPv6順序を制御可能(既定はverbatim)。(Node.js Docs: https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder ) -
ブラウザ側の差分(Chromium)
-
プロキシ/例外リストの扱い(
localhostや<loopback>特別扱い、bypass rules)。(Chromium Docs: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/docs/proxy.md ) - **HTTPS強制/HSTS(HTTP Strict Transport Security: HTTPSを強制する仕組み)**が有効だと、
http://localhostアクセスでHTTPSへアップグレード・ポリシー残存が影響。HSTSはchrome://net-internals/#hstsで削除可能、また「安全な接続を常に使用」を無効化可。(Google Support: https://support.google.com/chrome/answer/95472?hl=ja )
-
プロキシ/例外リストの扱い(
帰結:サーバ(Vite)は::1で待受、ブラウザは設定/ポリシーで::1へ直行できず拒否に見える。
恒久対処(推奨設定:IPv4 & HMRのIPv4固定)
要点: 127.0.0.1でLISTENし、HMR(WebSocket: 開発時に差分を即時反映する仕組み)も同一ホストに固定。最も再現性が高い。
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
host: "127.0.0.1", // IPv4に固定(localhostの解決揺れを排除)
port: 5173,
strictPort: true, // ポート自動変更を抑止(診断容易)
hmr: {
host: "127.0.0.1", // HMRのWS接続先もIPv4に固定
port: 5173
}
}
});
server.hostはCLIの--hostからも指定可。HMRオプション(host/port/clientPort/protocol/...)は公式が用途を明示(逆プロキシ等でHTTPとWSの到達先が分かれる場合)。(Vite Docs: https://vite.dev/config/server-options )
反映手順
- Vite停止 → 2) プロジェクト直下の
.vite削除 → 3)npm run dev再起動 → -
Get-NetTCPConnection -State Listen -LocalPort 5173で127.0.0.1:5173を確認 → - ブラウザは
http://127.0.0.1:5173で検証。
代替案(ネットワーク公開や両対応時の注意)
要点: 外部デバイス公開は--host/host: true等。IPv6両対応は環境差が強く、まずはIPv4固定が安定。
-
LAN/他端末からアクセスしたい
-
vite --hostまたはserver.host: true / "0.0.0.0"で外向けにLISTEN。既定localhostとの違いは公式参照。(Vite Docs: https://vite.dev/config/server-options#server-host )
-
-
IPv6も活かしたい
- Node/OSのデュアルスタック動作やブラウザのURL生成(
[::1]表記)次第で挙動が割れるため、実利優先ならIPv4固定を推奨。必要時はHMRのhost/clientPortを合わせて調整。(Vite Docs: https://vite.dev/config/server-options#server-hmr )
- Node/OSのデュアルスタック動作やブラウザのURL生成(
迅速な診断フロー(Windows/PowerShell)
要点: まずLISTEN先、次にOS疎通、最後にブラウザ層をクリーンに。
-
待受確認
Get-NetTCPConnection -State Listen -LocalPort 5173 | ft LocalAddress,LocalPort,OwningProcess::1のみ=IPv6専用待受。127.0.0.1=IPv4専用待受。 -
OS疎通(事実確認)
Test-NetConnection 127.0.0.1 -Port 5173 Test-NetConnection ::1 -Port 5173 curl -v http://127.0.0.1:5173/ curl -v http://[::1]:5173/ -
ブラウザ層(プロキシ/拡張を無視して検証:例・Chrome)
"%ProgramFiles%\Google\Chrome\Application\chrome.exe" ^ --user-data-dir=%TEMP%\ch-test --disable-extensions --no-proxy-server※プロキシ例外/既定挙動の詳細はChromiumのproxy bypass rulesを参照。(https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/docs/proxy.md )
-
hostsの基本形(確認)
127.0.0.1 localhost ::1 localhost※Windowsの既定hostsに戻す手順はMicrosoft公式を参照。
ブラウザ/OS側の整備ポイント
要点: プロキシとHSTSでつまずきやすい。まずローカル例外とHSTSクリア。
-
プロキシ/WPAD/PAC(自動構成や検出でプロキシを切り替える仕組み)
- システム設定は一時的にOFF、必須環境では例外に
localhost;127.0.0.1;::1;*.localhost。 - Bypass rulesの考え方(
<loopback>など)はChromiumの設計資料に記載。(https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/docs/proxy.md )
- システム設定は一時的にOFF、必須環境では例外に
-
HTTPS強制/HSTS
- Chrome設定「安全な接続を常に使用」をOFF、
chrome://net-internals/#hstsでlocalhostをDelete。(https://support.google.com/chrome/answer/95472?hl=ja )
- Chrome設定「安全な接続を常に使用」をOFF、
比較と選定理由
| 観点 | IPv4固定(推奨) | IPv6固定(::1) |
外向け公開(--host/0.0.0.0) |
|---|---|---|---|
| 概要 |
127.0.0.1でHTTP/WSとも統一 |
::1のみで待受 |
全IF/LANへ公開 |
| 学習コスト(学習に要する負荷) | 低(設定2箇所) | 中(URL角括弧やHMR考慮) | 中(CORS/allowedHosts検討) |
| 導入手順の単純さ | 高 | 中 | 中 |
| 保守性(変更に耐える容易さ) | 高(揺れが少ない) | 低(ブラウザ差分に影響) | 中(公開時の安全策が必要) |
| 実測ベンチ/安定度 | 高(全Chromiumで安定) | 低(ERR_CONNECTION_REFUSED事例) |
環境依存(代理/WS対応要) |
| ライセンス/商用可否 | 変わらず | 変わらず | 変わらず |
| 結論(用途適合) | ローカル開発の第一選択 | 特段の理由がある場合のみ | モバイル/実機検証・多端末共有 |
(外向け公開や逆プロキシ下では、HMRのprotocol/host/port/clientPortの調整が必要。Vite Docs参照: https://vite.dev/config/server-options#server-hmr )
ベストプラクティス(実践的指針)
-
vite.config.tsに**server.host = "127.0.0.1"/server.hmr.host = "127.0.0.1"**を恒久化。(https://vite.dev/config/server-options ) - URLは**
http://127.0.0.1:5173**で統一(localhostの揺れを排除)。 -
.viteキャッシュはトラブル時に削除→再起動。 - 代理/逆プロキシ環境ではHMR設定を明示(
clientPort含む)。(https://vite.dev/config/server-options#server-hmr ) - 共有やLAN公開は
--hostで意図的に実施し、server.allowedHostsも必要最小限に。(https://vite.dev/config/server-options#server-allowedhosts )
- 【参考文献/出典】
- Vite 5 Docs: Server Options(
server.host/server.hmr/CORS/allowedHosts)
https://vite.dev/config/server-options - Vite CLI Options(
--host,--strictPortなど)
https://vite.dev/guide/cli - Node.js Docs:
dns.setDefaultResultOrder/--dns-result-order(IPv4/IPv6順序)
https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder - Chromium Docs: Proxy bypass rules(
localhost/<loopback>等の扱い)
https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/docs/proxy.md - Google Support: Always use secure connections(HTTPS強制の設定と挙動)
https://support.google.com/chrome/answer/95472?hl=ja