如何正确拒绝websocket升级请求?
How to properly refuse websocket upgrade request?
有时候我想拒绝一个http客户端升级websocket连接的请求。
代码
(使用 go
的 Gin
和 gorilla/websocket
框架:)
要允许升级:
c, err := ctl.upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
err = c.WriteJSON(resp)
拒绝升级(由于请求参数无效):
if contentId == "" || !exists {
// FIXME: provide response in a way that ws client can recognize & show tip?
ctx.String(http.StatusBadRequest, "invalid or non-existing contentId")
return
}
说明:这里拒绝升级我只是return一个http400
代码,然后终止连接,并没有做升级完全没有。
问题
使用about代码拒绝websocket升级请求的问题是,websocket客户端(例如js
),无法读取数据 (文本或 json) 在我的回复中。
代码 - 客户端 (js
):
ws.onerror = function (evt) {
// TOOD: handle error, (e.g print error msg?),
print("ERROR");
}
它确实在拒绝时打印了 "ERROR"
,但是在检查了关于 evt
对象的 chrome 开发者工具之后,找不到获取服务器响应数据的方法,所以我无法向前端显示小费 UI,原因是拒绝。
问题
- 如何正确拒绝websocket升级请求,让客户端能够收到returned reason/data? (例如 client 是
js
,server 是 go
/ gin
/ gorilla/websocket
) .
- 除了 return 像
400
这样的 http 代码,有没有更好的方法来拒绝 websocket 升级请求?
要拒绝 websocket 连接,请不要按照问题中的描述升级连接。
浏览器 API 不提供有关连接被拒绝原因的信息,因为该信息可能违反 same-origin policy。
执行以下操作将错误原因发送回客户端应用程序或用户:
- 升级连接。
- 发送一条包含错误原因的关闭消息。
- 关闭连接。
这是一个例子:
c, err := ctl.upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
if err != nil {
// TODO: handle error
}
if contentId == "" || !exists {
c.WriteMessage(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.ClosePolicyViolation,
"bad content id or not exist"))
c.Close()
return
}
// Continue with non-error case here.
从 JS 中的关闭处理程序访问原因:
ws.onclose = function (evt) {
if (evt.code == 1008) { // 1008 is policy violation
console.log(evt.reason)
}
}
有时候我想拒绝一个http客户端升级websocket连接的请求。
代码
(使用 go
的 Gin
和 gorilla/websocket
框架:)
要允许升级:
c, err := ctl.upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
err = c.WriteJSON(resp)
拒绝升级(由于请求参数无效):
if contentId == "" || !exists {
// FIXME: provide response in a way that ws client can recognize & show tip?
ctx.String(http.StatusBadRequest, "invalid or non-existing contentId")
return
}
说明:这里拒绝升级我只是return一个http400
代码,然后终止连接,并没有做升级完全没有。
问题
使用about代码拒绝websocket升级请求的问题是,websocket客户端(例如js
),无法读取数据 (文本或 json) 在我的回复中。
代码 - 客户端 (js
):
ws.onerror = function (evt) {
// TOOD: handle error, (e.g print error msg?),
print("ERROR");
}
它确实在拒绝时打印了 "ERROR"
,但是在检查了关于 evt
对象的 chrome 开发者工具之后,找不到获取服务器响应数据的方法,所以我无法向前端显示小费 UI,原因是拒绝。
问题
- 如何正确拒绝websocket升级请求,让客户端能够收到returned reason/data? (例如 client 是
js
,server 是go
/gin
/gorilla/websocket
) . - 除了 return 像
400
这样的 http 代码,有没有更好的方法来拒绝 websocket 升级请求?
要拒绝 websocket 连接,请不要按照问题中的描述升级连接。 浏览器 API 不提供有关连接被拒绝原因的信息,因为该信息可能违反 same-origin policy。
执行以下操作将错误原因发送回客户端应用程序或用户:
- 升级连接。
- 发送一条包含错误原因的关闭消息。
- 关闭连接。
这是一个例子:
c, err := ctl.upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
if err != nil {
// TODO: handle error
}
if contentId == "" || !exists {
c.WriteMessage(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.ClosePolicyViolation,
"bad content id or not exist"))
c.Close()
return
}
// Continue with non-error case here.
从 JS 中的关闭处理程序访问原因:
ws.onclose = function (evt) {
if (evt.code == 1008) { // 1008 is policy violation
console.log(evt.reason)
}
}