
本教程旨在解决go语言websocket服务器在处理客户端连接时常见的403 forbidden错误,该问题通常源于go.net/websocket包默认的origin头部校验机制。文章将深入解释错误原因,并提供使用websocket.server进行灵活配置的解决方案,确保服务器能够正确响应各类websocket客户端请求,构建稳定可靠的websocket服务。
在Go语言中搭建WebSocket服务器,通常会利用code.google.com/p/go.net/websocket包(请注意,此包为早期版本,生产环境建议考虑github.com/gorilla/websocket或net/http的升级功能)。一个简单的WebSocket Echo服务器可以接收客户端发送的消息并回传。以下是一个基础的实现示例:
package main
import (
"fmt"
"code.google.com/p/go.net/websocket"
"net/http"
)
// webHandler 处理WebSocket连接,接收并打印消息,然后回传
func webHandler(ws *websocket.Conn) {
var s string
// 从WebSocket连接读取数据
if _, err := fmt.Fscan(ws, &s); err != nil {
fmt.Printf("Error reading from websocket: %v\n", err)
return
}
fmt.Println("Received: ", s)
// 将消息回传给客户端
if _, err := fmt.Fprint(ws, "Echo: "+s); err != nil {
fmt.Printf("Error writing to websocket: %v\n", err)
}
}
func main() {
fmt.Println("Starting WebSocket server on :8080")
// 使用websocket.Handler注册WebSocket处理函数
// 默认情况下,websocket.Handler会执行Origin头部校验
http.Handle("/echo", websocket.Handler(webHandler))
// 启动HTTP服务器监听
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}配套的J*aScript客户端连接代码如下:
// 创建WebSocket连接
ws = new WebSocket("ws://localhost:8080/echo");
// 连接成功时触发
ws.onopen = function(event) {
console.log("WebSocket connection opened.");
// 连接建立后发送一条消息
ws.send("Hello from client!");
};
// 收到服务器消息时触发
ws.onmessage = function(e) {
console.log("WebSocket message received: " + e.data);
};
// 连接发生错误时触发
ws.onerror = function(error) {
console.error("WebSocket error: ", error);
};
// 连接关闭时触发
ws.onclose = function(event) {
console.log("WebSocket connection closed:", event.code, event.reason);
};然而,当尝试使用上述配置的Go服务器与J*aScript客户端连接时,可能会在浏览器控制台看到类似WebSocket connection to 'ws://localhost:8080/echo' failed: Unexpected response code: 403的错误信息。
这个403 Forbidden错误并非表示认证失败,而是与code.google.com/p/go.net/websocket包内部的Origin头部校验机制密切相关。websocket.Handler在默认情况下,会检查HTTP请求中的Origin头部是否是一个有效的URL。
Origin头部是Web浏览器在发起跨域请求(包括WebSocket连接)时自动添加的一个安全特性,它指示了请求发起的源(协议、域名和端口)。websocket.Handler默认会验证这个Origin头部,如果出现以下情况,它可能会拒绝连接:
在上述任何一种情况下,websocket.Handler都会拒绝连接,并返回403状态码。这对于Web浏览器客户端而言是一种重要的安全保障,可以防止恶意网站发起WebSocket连接。然而,对于需要连接非浏览器客户端(如桌面应用、移动应用或服务器间通信)或在特定开发场景下,这种默认的严格校验可能会造成困扰。
Copymatic
Cowriter是一款AI写作工具,可以通过为你生成内容来帮助你加快写作速度和激发写作灵感。
149
查看详情
为了解决Origin校验导致的403错误,我们需要更精细地控制WebSocket连接的握手过程。code.google.com/p/go.net/websocket包提供了websocket.Server结构体,它允许我们自定义握手逻辑,特别是对Origin头部的处理。
通过websocket.Server,我们可以选择禁用默认的Origin校验,或者实现自定义的校验逻辑。对于需要接受非浏览器客户端或Origin头部可能不符合默认校验规则的场景,使用websocket.Server是更灵活且强大的选择。
以下是修改后的Go服务器代码,它使用websocket.Server来处理WebSocket连接,从而绕过默认的Origin校验:
package main
import (
"fmt"
"code.google.com/p/go.net/websocket"
"net/http"
)
// webHandler 保持不变,处理WebSocket连接的业务逻辑
func webHandler(ws *websocket.Conn) {
var s string
if _, err := fmt.Fscan(ws, &s); err != nil {
fmt.Printf("Error reading from websocket: %v\n", err)
return
}
fmt.Println("Received: ", s)
// 示例:回传消息
if _, err := fmt.Fprint(ws, "Echo: "+s); err != nil {
fmt.Printf("Error writing to websocket: %v\n", err)
}
}
func main() {
fmt.Println("Starting WebSocket server on :8080 with custom Origin handling")
// 使用http.HandleFunc注册一个普通的HTTP处理函数
// 在这个处理函数内部,我们创建并使用websocket.Server实例
http.HandleFunc("/echo",
func (w http.ResponseWriter, req *http.Request) {
// 创建websocket.Server实例
// 将webHandler作为其Handler。
// 关键点:当websocket.Server的Handshake字段为nil时,它不会执行Origin校验,
// 而是接受所有连接。这与websocket.Handler的默认行为不同。
s := websocket.Server{Handler: websocket.Handler(webHandler)}
// 调用ServeHTTP来处理当前的HTTP请求,将其升级为WebSocket连接
s.ServeHTTP(w, req)
})
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}通过这种方式,websocket.Server在处理请求时,如果其Handshake字段为nil,它将不会执行默认的Origin校验,从而允许各种客户端(包括那些不发送Origin头部或发送不符合默认校验规则Origin头部的客户端)成功建立WebSocket连接。
通过理解go.net/websocket包中Origin校验的机制,并恰当地利用websocket.Server,我们可以灵活地构建Go语言WebSocket服务器,以适应不同类型的客户端连接需求,避免常见的403错误,并根据实际场景平衡安全性和便利性。
以上就是Go语言WebSocket服务器:解决403 Origin校验错误与灵活配置的详细内容,更多请关注其它相关文章!
# 情况下
# seo搜索截流
# 苏州网站建设外包
# 优化网站设计流程排版
# 山西seo服务加盟公司
# 超市会员网站怎么做推广
# 芜湖网站群推广哪家好些
# 易趣网站推广规划
# 好的龙华网站建设
# 移动网站建设哪家便宜
# youn-seo choi
# 是一种
# 加载
# 器中
# 临时文件
# 不符合
# javascript
# 回传
# 自定义
# 是一个
# 客户端
# 跨域
# ai
# 工具
# websocket
# 端口
# 浏览器
# go语言
# github
# go
# git
# java
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
Excel如何设置动态下拉菜单_Excel表格下拉选项快速方法
《撕歌》会员开通方法
Excel宏怎么删除_Excel中删除宏的详细操作流程
如何查询国外邮政编码_国外邮政编码查询的多种有效途径
优化Leaflet弹出层图片显示:条件渲染策略
微博网页版入口链接 微博网页版在线互动平台
《sketchbook》选中部分图案移动方法
荣耀Magic6 Pro拍照成像偏暗_荣耀Magic6 Pro夜景优化
Flexbox布局中Stencil组件宽度不显示问题解析与:host尺寸控制
win11如何运行chkdsk命令 Win11检查和修复磁盘逻辑错误教程【修复】
汽水音乐在线听歌网页版 汽水音乐在线听歌网页版入口
使用 .htaccess 正确配置 WordPress 子目录重定向与路径保留
Chart.js 教程:自定义插件实现图表与图例间距调整
《健康大兴》注册方法介绍
Django模型动态关联检查:高效管理复杂关系
解决Pandas DataFrame高度碎片化警告:高效创建多列的策略
c++类和对象到底是什么_c++面向对象编程基础
《虎扑》取消评分记录方法
PHP页面重载时变量值不重置的实现方法
《procreate》绘制渐变效果教程
《花瓣》创建专辑方法
Sublime怎么自动添加CSS前缀_Sublime安装Autoprefixer插件
如何在Python中安全地将环境变量转换为整数并满足Mypy类型检查
《东方航空》添加乘机人方法
win11怎么启用或禁用休眠 Win11 powercfg命令管理休眠文件【技巧】
qq邮箱格式填写示例 qq邮箱标准填写规范
iSpring三分屏制作教程
FullCalendar自定义按钮样式定制指南
c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化
iPhone 13 Pro Max如何设置桌面小组件_iPhone 13 Pro Max小组件添加指南
OTT月报 | 2025年9月智能电视大数据报告
Golang如何使用gRPC拦截器实现日志收集_Golang gRPC拦截器日志收集实践
《鹿路通》退余额方法
如何在mysql中使用索引提示_mysql索引提示优化方法
sublime如何配置PHP开发环境_在sublime中运行与调试PHP代码
cad加载的线型看不见怎么办_cad线型不可见问题解决方法
Lar*el Eloquent中通过Join查询关联数据表:解决多行子查询问题
大众点评了却看不到是怎么回事
AI图层蒙版怎么用_AI图层蒙版应用技巧与设计实例
Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧
《下一站江湖2》风神腿获取攻略
MacBook Pro词典使用指南
《大学搜题酱》官网地址登录
AO3永久镜像入口开放_AO3最新网址兼容所有浏览器
WooCommerce购物车:强制显示所有交叉销售商品教程
TikTok网页版入口快速访问 TikTok官网账号登录方法
php如何实现多域名共享session_php存储session到redis与跨域读取配置
个人所得税办理入口 个人所得税综合所得年度汇算入口
Go语言中方法接收器的选择:值类型还是指针类型?
漫蛙官网(首页入口)_漫蛙漫画稳定访问教程分享
2025-11-06
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。