페이지 URI에 상대적인 WebSocket URI를 구성하는 방법은 무엇입니까?


95

브라우저 측에서 페이지 URI를 기준으로 WebSocket URI를 구성하고 싶습니다. 제 경우에는 HTTP 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

내가 현재하고있는 것은 처음 4 개의 "http"문자를 "ws"로 바꾸고 "/ to / ws"를 추가하는 것입니다. 더 좋은 방법이 있습니까?


1
무슨 뜻 path/to/ws입니까? 이것이 정확히 어디로 연결됩니까? 감사합니다
slevin 2014 년

답변:


96

웹 서버가 WebSocket (또는 WebSocket 처리기 모듈)을 지원하는 경우 동일한 호스트 및 포트를 사용하고 표시하는 것과 같이 스키마를 변경할 수 있습니다. 웹 서버와 Websocket 서버 / 모듈을 함께 실행하기위한 많은 옵션이 있습니다.

window.location 전역의 개별 조각을보고 블라인드 문자열 대체를 수행하는 대신 다시 결합하는 것이 좋습니다.

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

일부 웹 서버 (예 : Jetty 기반 서버)는 현재 경로 (업그레이드 헤더가 아닌)를 사용하여 특정 요청이 WebSocket 핸들러에 전달되어야하는지 여부를 결정합니다. 따라서 원하는 방식으로 경로를 변환 할 수 있는지 여부가 제한 될 수 있습니다.


경로 이름을 사용하여 'ws : // localhost : 8080 / Chat / index.html / chat'과 같은 URL을 얻습니다. 그리고 그것은 정확하지 않은 URL입니다.
Denis535

1
@ wishmaster35 처리 방법은 사용 사례 및 설정에 따라 다릅니다. example.com/part1/part2가 part1이라는 디렉토리 내의 part2라는 파일을 참조 하는지 , part2가 part1 내의 디렉토리인지 또는 완전히 다른 것인지 (예 : part1과 part2는 개체 데이터베이스). URL에서 "경로"의 의미는 웹 서버 및 해당 구성에 달려 있습니다. "* .html"로 끝나는 모든 항목을 제거해야한다고 추론 할 수 있습니다. 그러나 이것은 특정 설정 및 요구 사항에 따라 다릅니다.
kanaka

3
@socketpair 아니요, 포트가 있습니다. window.location.host에는 호스트 이름과 포트가 포함됩니다 (location.hostname은 호스트 이름 전용 임).
kanaka

생략 할 수 있습니까 "/to/ws"? 그렇지 않은 경우 해당 부품의 가치는 무엇입니까?
TET

1
@tet은 초기 WebSocket 연결이 설정 될 때 사용되는 GET 요청 경로 (즉, HTTP GET 경로)입니다. 사용 여부는 설정에 따라 다릅니다. 단일 목적 웹 소켓 서버가있는 경우 (정적 웹 파일도 제공 할 수 있음) 아마도 무시됩니다. 전용 웹 서버 뒤에 여러 개의 웹 소켓 서버가있는 경우 해당 경로는 올바른 웹 소켓 서버로 라우팅하는 데 사용될 수 있습니다. 경로는 토큰 전달 (예 : 쿼리 매개 변수를 통해) 등과 같은 웹 소켓 서버에서 다른 목적으로도 사용할 수 있습니다.
kanaka

32

다음은 80 또는 443이 아닌 경우 tcp 포트를 추가하는 내 버전입니다.

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

14
port mangling을 할 필요가 없습니다. location.hostname 대신 location.host를 사용하세요
kanaka

24

Window.URL API를 사용하여 - https://developer.mozilla.org/en-US/docs/Web/API/Window/URL

http (s), 포트 등에서 작동합니다.

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

https / wss에서도 작동한다는 점을 언급해야합니다 ( 'http'를 'ws'=> 'https'=> 'wss'로
대체

7

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

location.path가 올바르지 않습니다. 경로명을 사용해야합니다.
Denis535

@ wishmaster35 : 좋은 캐치! 결정된.
Pavel

4

쉬운:

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

URL 표시 줄 안에있는 경우 /^http/대신 사용 합니다. 'http'http
phk

window.location.href는 전체 경로를 포함하므로 /page.html/path/to/ws
Eadz

위치에 http가 포함되어 있으면 문제가 될 수 있습니다. 예 : testhttp.com/http.html
Dániel Kis

1
로 : 그냥 '// HTTP'대신 'WS : //'간단한 아이디어는 어떤 개발자, 심지어 후배에게 분명해야
막심 Kostromin에게

2

localhost에서는 컨텍스트 경로를 고려해야합니다.

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
컨텍스트 경로 란 무엇입니까?
amirouche

1

타이프 스크립트에서 :

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"));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.