0. 概要
状況
パソコンで立ち上げたWebサーバにスマートフォンで接続したい。
なにが問題か
スマートフォンからではlocalhostで接続できない。パソコンのIPを調べるのは面倒である。
解決方法
スマートフォンから接続可能なURLをQRコードで表示する。
1. 処理の流れ
URLの取得
window.location.href によって取得する。
ホスト名部分をIPアドレスに変える
通常は localhost になっているホスト名を、外部のPCやスマートフォンから接続できるようにIPアドレスの数値標記に変える。
QRコードを作成する
JavaScriptでQRコードを作成できるライブラリ(qrious)を使ってIPアドレスに変換したURLをQRコードで表示する。
2. HTML部分
<div>
<!-- urlの表示用 -->
<span id="own_url"></span>
</div>
<div>
<!-- QRコード, サイズはライブラリ(qrious)が設定してくれる -->
<canvas id="qr_code"></canvas>
</div>
bodyタグの中に記述してください。
3. QRコード作成ライブラリの読み込み
<!-- QRコード作成ライブラリ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
bodyタグの下やheadタグの中で記述してください。
4. JavaScript部分
// URL、localhostの部分がipアドレスの数値になるものの元
const testurl = window.location.href;
// プロトコル部分の抽出
const proto = /^([a-zA-Z][a-zA-Z\d+\-.]*):\/\//.exec(testurl)?.[1];
// ポート番号の抽出、デフォルトのポート番号の場合、空文字になる。
const port = /(:\d+)/.exec(testurl)?.[1] ?? "";
// パス部分の抽出
const path = /^(?:[^:]+:\/\/)?[^\/]+(\/.*)/.exec(testurl)?.[1];
// ipは、WebRTCを使って取得する。参考: https://stackoverflow.com/questions/20194722/can-you-get-a-users-local-lan-ip-address-via-javascript
const ip = await new Promise((resolve, reject) => {
const pc = new RTCPeerConnection({ iceServers: [] });
pc.createDataChannel("");
pc.createOffer(pc.setLocalDescription.bind(pc), () => { });
pc.onicecandidate = (ice) => {
if (ice?.candidate && ice.candidate.candidate) {
const ip = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}|([a-f0-9-]+\.local))/
.exec(ice.candidate.candidate)[1];
pc.onicecandidate = () => { };
resolve(ip);
}
}
});
// localhostがipの数値になったURLを再構成する。
const own_url = proto + "://" + ip + port + path;
// URLの表示
document.getElementById("own_url").innerText = own_url;
// QRコードの作成
const qr = new QRious({
element: document.getElementById("qr_code"),
value: own_url,
});
scriptタグの中で記述してください。scriptタグは、type="module"となっていることを想定しています。
IPアドレスはWebRTCというリアルタイムで通信することを想定したライブラリによって数値を取得しています。URLのそれ以外の部分は正規表現によって抜き出して再構成しています。
5. 実行結果
パソコンでWebサーバに接続した画面です。パソコンからlocalhostで接続しても、10.xx.xx.xxのようにURLがIPアドレスの数値になってQRコードが作成されます。
このQRコードをスマートフォンで読み込むと、パソコンで立ち上げたWebサーバに接続することができます。
6. 制限
- スマートフォンは、Webサーバのパソコンと同じネットワークに入っていないと通常は接続できません
- パソコンでHTMLファイルをダブルクリックして表示するときには、スマートフォンからは接続できません
- https://localhost/ とするとmDNSのホスト名が取得されますが、2024年10月13日時点では、Android 12からmDNSのホスト名に接続することができません
7. パソコンで立ち上げるWebサーバについて
pythonをインストールしているなら、python -m http.serverで実行したフォルダをルートとしたWebサーバを起動することができます。