如何构造相对于页面URI的WebSocket URI?

如何构造相对于页面URI的WebSocket URI?,websocket,uri,relative-path,Websocket,Uri,Relative Path,我想构造一个相对于浏览器端页面URI的WebSocket URI。比如,在我的例子中,像 http://example.com:8000/path https://example.com:8000/path 到 我目前正在做的是将前4个字母“http”替换为“ws”,并在其后面附加“/to/ws”。有什么更好的方法吗?如果您的Web服务器支持WebSocket(或WebSocket处理程序模块),那么您可以使用相同的主机和端口,只需按照所示更改方案即可。有许多选项可用于同时运行Web服务器和W

我想构造一个相对于浏览器端页面URI的WebSocket URI。比如,在我的例子中,像

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


我目前正在做的是将前4个字母“http”替换为“ws”,并在其后面附加“/to/ws”。有什么更好的方法吗?

如果您的Web服务器支持WebSocket(或WebSocket处理程序模块),那么您可以使用相同的主机和端口,只需按照所示更改方案即可。有许多选项可用于同时运行Web服务器和Websocket服务器/模块

我建议您查看window.location global的各个部分,并将它们重新连接在一起,而不是进行盲字符串替换

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处理程序。因此,您可能会受限于是否可以按您想要的方式转换路径。

以下是我的版本,它添加了tcp端口,以防端口不是80或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;
}
编辑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");

假设您的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');

在本地主机上,应考虑上下文路径。

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;
}
简单:


使用Window.URL API-

适用于http、端口等

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
在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"));
简易解决方案,ws和端口,经过测试:
你所说的路径/to/ws是什么意思?这条路到底通向哪里?感谢“ws://”+window.location.host+“:6666”-donelocation.path不正确。您应该使用路径名。@wishmaster35:捕捉得好!修正了。使用路径名我得到这样的url:'ws://localhost:8080/Chat/index.html/Chat'。它是不正确的url。@wishmaster35如何处理它将取决于您的用例和设置。没有可靠的方法来确定是否引用了名为part1的目录中名为part2的文件,或者part2是part1中的目录,还是完全不同的目录(例如part1和part2是对象数据库中的键)。URL中“路径”的含义取决于web服务器及其配置。您可以推断任何以“*.html”结尾的内容都应该删除。但同样,这取决于您的具体设置和要求。@socketpair否,端口在那里。window.location.host包含主机名和端口(location.hostname仅为主机名)。是否可以省略
“/to/ws”
?如果不是,该部分的值应该是多少?@tet这是在建立初始WebSocket连接时使用的GET请求路径(即HTTP GET路径)。是否使用取决于您的设置。如果您有一个单一用途的websocket服务器(可能碰巧也提供静态web文件),那么它可能会被忽略。如果在专用web服务器后面有多个websocket服务器,则该路径可能用于路由到正确的websocket服务器。websocket服务器还可以将该路径用于其他目的,例如传递令牌(例如,通过查询参数)等。您不需要进行端口管理,只需使用location.host而不是location.hostname什么是上下文路径?我会使用
/^http/
而不是
'http'
,以防
http
在URL栏中。window.location.href包含完整路径,因此如果您的位置包含http,则可能会出现问题。例如:将“http://”替换为“ws://”,这个简单的想法对任何开发人员来说都是显而易见的,即使是juniorsI也应该提到,这也适用于https/wss(将“http”替换为“ws”=>“https”=>“wss”)
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"));
var ws = new WebSocket("ws://" + window.location.host + ":6666");

ws.onopen = function() { ws.send( .. etc