2012-05-02 77 views
68

我想在瀏覽器端構建一個相對於頁面URI的WebSocket URI。就是說,在我的情況下轉換HTTP的URI像如何構建相對於頁面URI的WebSocket 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 

我在做什麼現在是「WS」替換第4個字母「HTTP」,並追加「/到/ ws「。有沒有更好的方法呢?

+1

你說的'路徑/要/ ws'是什麼意思?這導致了什麼?謝謝 – slevin

回答

66

如果您的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服務器(即,基於碼頭的)目前使用的路徑(而不是升級頭),以確定是否一個特定的請求應該到網頁套接字句柄傳遞。所以你可能會受限於你是否可以按照你想要的方式改變路徑。

+0

使用路徑名我得到這樣的網址:'ws:// localhost:8080 /聊天/索引。HTML /聊天」。這是不正確的網址。 – wishmaster35

+1

@ wishmaster35如何處理將取決於您的用例和設置。沒有確定的方法來確定http://example.com/part1/part2是否在名爲part1的目錄中指定名爲part2的文件,或者其他part2是part1中的目錄,還是完全不同的目錄(例如part1和part2是對象數據庫中的鍵)。 URL中「路徑」的含義取決於Web服務器及其配置。你可以推斷任何以「* .html」結尾的內容都應該被刪除。但是,這又取決於您的具體設置和要求。 – kanaka

+0

你忘了也端口! – socketpair

27

這裏是我的版本,它增加了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"); 
+11

你不需要做端口忙玲,只是使用的location.host代替location.hostname – kanaka

4

假設你的WebSocket服務器監聽Ø n個相同的端口從被請求的頁面時,我建議:

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'); 
+0

位置。路徑不正確。你應該使用路徑名。 – wishmaster35

+0

@ wishmaster35:趕上!固定。 – Pavel

2

在本地主機上,你應該考慮上下文路徑。

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

什麼是上下文路徑? – amirouche

0

容易:

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

我會使用'/^http /'而不是''http''以防'http'在URL欄內。 – phk

+0

window.location.href包括完整路徑,所以你可能最終/page.html/path/to/ws – Eadz

+0

如果你的位置包含HTTP可能會有問題。例如:http://testhttp.com/http.html –

0

在打字稿:

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