Je souhaite créer un URI WebSocket par rapport à l'URI de la page côté navigateur. Dites, dans mon cas, convertir des URI HTTP comme
http://example.com:8000/path
https://example.com:8000/path
à
ws://example.com:8000/path/to/ws
wss://example.com:8000/path/to/ws
Ce que je fais actuellement, c'est remplacer les 4 premières lettres "http" par "ws" et y ajouter "/ to/ws". Y a-t-il un meilleur moyen pour cela?
Si votre serveur Web prend en charge WebSockets (ou un module de gestionnaire WebSocket), vous pouvez utiliser le même hôte et le même port et simplement modifier le schéma tel que vous le montrez. Il existe de nombreuses options pour exécuter un serveur Web et un serveur/module Websocket ensemble.
Je suggérerais que vous examiniez les différentes parties du fichier window.location global et que vous les réunissiez au lieu de remplacer les chaînes aveugles.
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";
Notez que certains serveurs Web (c’est-à-dire ceux basés sur Jetty) utilisent actuellement le chemin (plutôt que l’en-tête de mise à niveau) pour déterminer si une demande spécifique doit être transmise au gestionnaire WebSocket. Vous ne pouvez donc pas savoir si vous pouvez transformer le chemin comme vous le souhaitez.
Voici ma version qui ajoute le port TCP au cas où ce ne serait pas 80 ou 443:
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;
}
Edit 1: Version améliorée par suggestion de @kanaka:
function url(s) {
var l = window.location;
return ((l.protocol === "https:") ? "wss://" : "ws://") + l.Host + l.pathname + s;
}
Edit 2: Aujourd'hui, je crée le WebSocket
this:
var s = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.Host + "/ws");
Utilisation de l’API Window.URL - https://developer.mozilla.org/en-US/docs/Web/API/Window/URL
Fonctionne avec http (s), ports, etc.
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
En supposant que votre serveur WebSocket écoute sur le même port que celui à partir duquel la page est demandée, je suggérerais:
function createWebSocket(path) {
var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
return new WebSocket(protocolPrefix + '//' + location.Host + path);
}
Ensuite, dans votre cas, appelez-le comme suit:
var socket = createWebSocket(location.pathname + '/to/ws');
Sur localhost, vous devriez considérer le chemin du contexte.
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;
}
facile:
location.href.replace(/^http/, 'ws') + '/to/ws'
// or if you hate regexp:
location.href.replace('http://', 'ws://').replace('https://', 'wss://') + '/to/ws'
Dans 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 "";
}
}
}
Usage:
alert(WebsocketUtils.websocketUrlByPath("/websocket"));