I want to construct a WebSocket URI relative to the page URI at the browser side. Say, in my case convert HTTP URIs like
http://example.com:8000/path
https://example.com:8000/path
to
ws://example.com:8000/path/to/ws
wss://example.com:8000/path/to/ws
What I'm doing currently is replace the first 4 letters "http" by "ws", and append "/to/ws" to it. Is there any better way for that?
If your Web server has support for WebSockets (or a WebSocket handler module) then you can use the same host and port and just change the scheme like you are showing. There are many options for running a Web server and Websocket server/module together.
I would suggest that you look at the individual pieces of the window.location global and join them back together instead of doing blind string substitution.
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";
Note that some web servers (i.e. Jetty based ones) currently use the path (rather than the upgrade header) to determine whether a specific request should be passed on to the WebSocket handler. So you may be limited in whether you can transform the path in the way you want.
Here is my version which adds the tcp port in case it's not 80 or 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: Improved version as by suggestion of @kanaka :
function url(s) {
var l = window.location;
return ((l.protocol === "https:") ? "wss://" : "ws://") + l.host + l.pathname + s;
}
Edit 2: Nowadays I create the WebSocket
this:
var s = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/ws");
Using the Window.URL API - https://developer.mozilla.org/en-US/docs/Web/API/Window/URL
Works with 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
Assuming your WebSocket server is listening on the same port as from which the page is being requested, I would suggest:
function createWebSocket(path) {
var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
return new WebSocket(protocolPrefix + '//' + location.host + path);
}
Then, for your case, call it as follows:
var socket = createWebSocket(location.pathname + '/to/ws');
On localhost you should consider context path.
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;
}
In 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"));
easy:
location.href.replace(/^http/, 'ws') + '/to/ws'
// or if you hate regexp:
location.href.replace('http://', 'ws://').replace('https://', 'wss://') + '/to/ws'
来源:https://stackoverflow.com/questions/10406930/how-to-construct-a-websocket-uri-relative-to-the-page-uri