Sayfa URI'sine göre bir WebSocket URI'si nasıl oluşturulur?


98

Tarayıcı tarafında sayfa URI'sine göre bir WebSocket URI'si oluşturmak istiyorum. Diyelim ki benim durumumda HTTP URI'larını şu şekilde dönüştürün:

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

-e

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

Şu anda yaptığım şey ilk 4 harf olan "http" yi "ws" ile değiştirmek ve ona "/ to / ws" yi eklemek. Bunun daha iyi bir yolu var mı?


1
Ne demek istiyorsun path/to/ws? Bu tam olarak nereye gidiyor? Teşekkürler
slevin

"ws: //" + window.location.host + ": 6666" -done
Fattie

Yanıtlar:


99

Web sunucunuzda WebSocket (veya bir WebSocket işleyici modülü) desteği varsa, aynı ana bilgisayarı ve bağlantı noktasını kullanabilir ve yalnızca gösterdiğiniz gibi düzeni değiştirebilirsiniz. Bir Web sunucusu ve Websocket sunucusu / modülünü birlikte çalıştırmak için birçok seçenek vardır.

Kör dizge ikamesi yapmak yerine window.location global'in tek tek parçalarına bakmanızı ve onları tekrar birleştirmenizi öneririm.

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";

Bazı web sunucularının (yani Jetty tabanlı olanlar), belirli bir isteğin WebSocket işleyicisine iletilmesi gerekip gerekmediğini belirlemek için şu anda yolu (yükseltme başlığı yerine) kullandığına dikkat edin. Bu nedenle, yolu istediğiniz şekilde dönüştürebilme konusunda sınırlı kalabilirsiniz.


Yol adını kullanarak şöyle bir url alıyorum: 'ws: // localhost: 8080 / Chat / index.html / chat'. Ve düzeltilmemiş url.
Denis535

1
@ wishmaster35 bunun nasıl ele alınacağı, sizin kullanım durumunuza ve kurulumunuza bağlı olacaktır. Example.com/part1/part2'nin part1 adlı bir dizindeki part2 adlı bir dosyaya mı yoksa part2'nin part1 içinde bir dizin mi yoksa tamamen farklı bir şey mi (örneğin, part1 ve part2 içindeki anahtarlar olduğunu) belirlemenin kesin bir yolu yoktur. bir nesne veritabanı). Bir URL'deki "yolların" anlamı web sunucusuna ve yapılandırmasına bağlıdır. "* .Html" ile biten her şeyin çıkarılması gerektiği sonucuna varabilirsiniz. Ancak yine, bu sizin özel kurulumunuza ve gereksinimlerinize bağlı olacaktır.
kanaka

3
@socketpair hayır, bağlantı noktası var. window.location.host, ana bilgisayar adını ve bağlantı noktasını içerir (location.hostname yalnızca ana bilgisayar adıdır).
kanaka

Çıkabilir miyim "/to/ws"? Değilse, o bölümün değeri ne olmalıdır?
tet

1
@tet, ilk WebSocket bağlantısı kurulduğunda kullanılan GET istek yoludur (yani HTTP GET yolu). Kullanılıp kullanılmayacağı kurulumunuza bağlıdır. Tek amaçlı bir websocket sunucunuz varsa (bu aynı zamanda statik web dosyalarını da sunabilir) büyük olasılıkla yok sayılır. Adanmış bir web sunucusunun arkasında birden fazla websocket sunucunuz varsa, yol muhtemelen doğru websocket sunucusuna yönlendirmek için kullanılıyor demektir. Yol, websocket sunucusu tarafından jeton iletme gibi başka amaçlar için de kullanılabilir (ör. Sorgu parametreleri aracılığıyla), vb.
kanaka

35

İşte 80 veya 443 olmaması durumunda tcp bağlantı noktasını ekleyen sürümüm:

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;
}

Düzenleme 1: @kanaka'nın önerisine göre geliştirilmiş sürüm:

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

Düzenleme 2: Bugünlerde şunu oluşturuyorum WebSocket:

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

14
Bağlantı noktası değiştirme işlemi yapmanıza gerek yok, sadece location.host yerine location.host'u kullanın.hostname
kanaka

25

Window.URL API'sini kullanma - https://developer.mozilla.org/en-US/docs/Web/API/Window/URL

Http (s), bağlantı noktaları vb. İle çalışır.

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

Bunun https / wss ile de çalıştığını belirtmeliyim ('http' yerine 'ws' => 'https' => 'wss')
Eadz

7

WebSocket sunucunuzun, sayfanın istendiği bağlantı noktasından dinlediğini varsayarsak, şunu öneririm:

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

Ardından, davanız için aşağıdaki şekilde arayın:

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

location.path doğru değil. Yol adını kullanmalısınız.
Denis535

@ wishmaster35: İyi yakaladın! Sabit.
Pavel

4

kolay:

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

Ben kullanırım /^http/yerine 'http'durumda sadece httpURL çubuğuna içindedir.
phk

window.location.href tam yolu içerir, böylece /page.html/path/to/ws
Eadz

Konumunuz http içeriyorsa sorunlu olabilir. Örneğin: testhttp.com/http.html
Dániel Kis

1
"Http: //" yi "ws: //" ile değiştirin, bu basit fikir tüm geliştiriciler için, hatta gençler için bile açık olmalıdır
Maksim Kostromin

2

Localhost'ta bağlam yolunu düşünmelisiniz.

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;
}

4
bağlam yolu nedir?
amirouche

2

Typcript'te:

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 "";
        }
    }
}

Kullanım:

alert(WebsocketUtils.websocketUrlByPath("/websocket"));

0

Son derece kolay çözüm, ws ve port, test edildi:

var ws = new WebSocket("ws://" + window.location.host + ":6666");

ws.onopen = function() { ws.send( .. etc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.