You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言使用httputil实现反向代理返回404错误如何解决

问题分析
  • 路由匹配规则冲突:Go 标准库的http.ServeMux对路由路径严格区分末尾斜杠,你源站注册的路由是/run,而代理默认转发后的路径是/run/(带末尾斜杠),无法匹配到注册的处理函数,因此返回404。
  • 反向代理路径拼接逻辑不符合预期:httputil.NewSingleHostReverseProxy默认会将客户端请求的路径直接追加到目标URL的路径之后,你初始化时传入的目标URL路径为/run/,如果要所有请求都固定转发到/run,默认拼接逻辑无法满足需求。
修复方案

方案1:固定所有代理请求转发到源站/run路径(适配当前代码需求)

直接修改反向代理的Director函数,重写转发路径和Host头,修正后的代理代码如下:

package main

import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    demoUrl, err := url.Parse("http://localhost:1000")
    if err != nil {
        log.Fatal(err)
        return
    }
    proxy := httputil.NewSingleHostReverseProxy(demoUrl)
    // 覆盖默认的Director逻辑
    originalDirector := proxy.Director
    proxy.Director = func(r *http.Request) {
        originalDirector(r)
        // 强制指定转发路径为/run,忽略客户端请求的路径
        r.URL.Path = "/run"
        // 修正Host头,避免源站做Host校验时不通过
        r.Host = demoUrl.Host
    }

    http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(rw, r)
    })
    log.Println("代理服务启动,监听端口:2000")
    _ = http.ListenAndServe(":2000", nil)
}

修改后访问http://localhost:2000即可正常拿到源站返回的I am running内容。

方案2:保留默认路径拼接逻辑

如果你希望代理路径和源站路径对应,比如访问代理http://localhost:2000/run转发到源站http://localhost:1000/run,可以做以下修改:

  1. 初始化反向代理的目标URL改为根路径:url.Parse("http://localhost:1000")
  2. 调整代理路由规则与源站路由保持一致即可,也可以直接将源站路由注册为/run/,适配带末尾斜杠的路径请求。

内容的提问来源于stack exchange,提问作者Ritik Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:45:03