web-dev-qa-db-ja.com

ページURIを基準にしてWebSocket URIを構築する方法は?

ブラウザー側でページURIに関連するWebSocket URIを構築したい。私の場合、次のようなHTTP URIを変換します

http://example.com:8000/path
https://example.com:8000/path

ws://example.com:8000/path/to/ws
wss://example.com:8000/path/to/ws

私が現在していることは、最初の4文字の「http」を「ws」に置き換え、「/ to/ws」を追加することです。そのためのより良い方法はありますか?

84
neuront

WebサーバーがWebSockets(またはWebSocketハンドラーモジュール)をサポートしている場合は、同じホストとポートを使用して、表示されているようにスキームを変更できます。 WebサーバーとWebsocketサーバー/モジュールを一緒に実行するための多くのオプションがあります。

Window.locationグローバルの個々の部分を見て、ブラインドストリング置換を行う代わりに、それらを結合し直すことをお勧めします。

var loc = window.location, new_uri;
if (loc.protocol === "https:") {
    new_uri = "wss:";
} else {
    new_uri = "ws:";
}
new_uri += "//" + loc.Host;
new_uri += loc.pathname + "/to/ws";

一部のWebサーバー(つまり、Jettyベースのもの)は現在、特定の要求をWebSocketハンドラーに渡す必要があるかどうかを判断するために(アップグレードヘッダーではなく)パスを使用していることに注意してください。そのため、パスを希望する方法で変換できるかどうかが制限される場合があります。

87
kanaka

80または443でない場合にtcpポートを追加する私のバージョンは次のとおりです。

function url(s) {
    var l = window.location;
    return ((l.protocol === "https:") ? "wss://" : "ws://") + l.hostname + (((l.port != 80) && (l.port != 443)) ? ":" + l.port : "") + l.pathname + s;
}

編集1:@kanakaの提案によるバージョンの改善:

function url(s) {
    var l = window.location;
    return ((l.protocol === "https:") ? "wss://" : "ws://") + l.Host + l.pathname + s;
}

編集2:最近、私はWebSocketこれを作成します:

var s = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.Host + "/ws");
32
yglodt

Window.URL APIの使用- https://developer.mozilla.org/en-US/docs/Web/API/Window/URL

Http(s)、ポートなどで動作します.

var url = new URL('/path/to/websocket', window.location.href);

url.protocol = url.protocol.replace('http', 'ws');

url.href // => ws://www.example.com:9999/path/to/websocket
13
Eadz

WebSocketサーバーが、ページが要求されているポートと同じポートでリッスンしていると仮定すると、次のことをお勧めします。

function createWebSocket(path) {
    var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
    return new WebSocket(protocolPrefix + '//' + location.Host + path);
}

次に、あなたの場合、次のように呼び出します。

var socket = createWebSocket(location.pathname + '/to/ws');
7
Pavel

ローカルホストでは、コンテキストパスを考慮する必要があります。

function wsURL(path) {
    var protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
    var url = protocol + location.Host;
    if(location.hostname === 'localhost') {
        url += '/' + location.pathname.split('/')[1]; // add context path
    }
    return url + path;
}
2
Deni35

簡単:

location.href.replace(/^http/, 'ws') + '/to/ws'
// or if you hate regexp:
location.href.replace('http://', 'ws://').replace('https://', 'wss://') + '/to/ws'
1

TypeScriptの場合:

export class WebsocketUtils {

    public static websocketUrlByPath(path) {
        return this.websocketProtocolByLocation() +
            window.location.hostname +
            this.websocketPortWithColonByLocation() +
            window.location.pathname +
            path;
    }

    private static websocketProtocolByLocation() {
        return window.location.protocol === "https:" ? "wss://" : "ws://";
    }

    private static websocketPortWithColonByLocation() {
        const defaultPort = window.location.protocol === "https:" ? "443" : "80";
        if (window.location.port !== defaultPort) {
            return ":" + window.location.port;
        } else {
            return "";
        }
    }
}

使用法:

alert(WebsocketUtils.websocketUrlByPath("/websocket"));
1
Dániel Kis