Axios请求Go后端时MongoDB Decode阶段报连接池超时错误
问题根因
- 核心报错是
context canceled,本质是传入MongoDB操作的上下文被提前终止,对应触发逻辑如下:- MongoDB Go驱动的
FindOne方法是懒执行逻辑:调用FindOne时仅构造结果对象,不会真正申请连接、执行查询,直到调用result.Decode()时才会用到传入的上下文发起实际数据库操作,这也是报错点固定出现在Decode行的原因。 - 跨域场景下请求被浏览器提前终止:Postman不存在浏览器同源策略限制,不会发送跨域预检请求,请求会持续保持连接直到服务端返回,因此上下文不会被提前取消;但浏览器端axios发起跨域POST请求时,会先发送OPTIONS方法的预检请求,当前后端未正确处理跨域配置时,浏览器会直接终止主请求,绑定在请求上的上下文会立刻触发cancel,等到Decode步骤申请数据库连接时,上下文已经是取消状态,就会抛出连接池获取连接超时的错误。
- 前端axios传参写法错误:
axios.post的第三个参数要求传入完整请求配置对象,现有代码直接将headers对象作为配置传入,会导致配置解析异常,加重跨域判定问题。
- MongoDB Go驱动的
解决方案
按以下顺序修改即可修复问题:
- 修正前端axios请求写法,将headers包裹在配置对象的headers字段中:
export async function validLogin(email, password) { const data = JSON.stringify({ email, password }); const requestConfig = { headers: { 'Content-Type': 'application/json;charset=UTF-8', } }; return await axios.post('http://localhost:1323/profile/valid', data, requestConfig) }
- 给Go后端的Echo框架添加CORS跨域中间件,放行OPTIONS预检请求,配置正确的跨域响应头,注意中间件要在注册业务路由前添加:
import "github.com/labstack/echo/v4/middleware" func main() { e := echo.New() // 注册CORS中间件 e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ // 开发环境可临时配置为*允许所有源,生产环境替换为前端实际部署域名 AllowOrigins: []string{"*"}, AllowMethods: []string{echo.GET, echo.POST, echo.OPTIONS}, AllowHeaders: []string{"Content-Type", "Authorization"}, })) // 后续注册路由、启动服务的原有逻辑保持不变... }
- 修正MongoDB操作传入的上下文,不要直接传入Echo的Context对象,优先取HTTP请求的原生标准库上下文,避免框架自定义Context的兼容问题:
func (p *profile)CheckInformationValid(ctx echo.Context,email string, password string, profile *models.Profile) (string, error) { filter := map[string]interface{}{"Email": email, "PassWord": password} // 取请求绑定的标准库context.Context传入Mongo操作 reqCtx := ctx.Request().Context() result := storage.GetInstance().FindOne(reqCtx, "profile",filter) fmt.Println(result) if result == nil { return "", errors.New("Check Information: user not find") } err := result.Decode(profile) if err != nil { fmt.Println(err) return "",errors.New("Error Decode Profile") } fmt.Println(profile) log.Infof("[CheckInformationValid] Object : %s \n", profile, "") return profile.UserId , nil }
内容的提问来源于stack exchange,提问作者Elisa Souza
相关产品推荐
相关产品推荐

