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

Go的NewSingleHostReverseProxy转发请求时重复查询参数问题

问题原因分析

你的反向代理出现查询参数重复,核心原因是:

  • 原请求的request.URL仍保留着初始的url查询参数,代理转发时会将这些参数追加到目标URL的参数之后,导致重复。
  • 你只修改了request.URL的Host和Scheme,但没有替换Path和查询参数,原请求的根路径/和附带的所有查询参数(包括url)被一并转发到目标服务器。
修复方案

需要对request.URL进行完整替换,覆盖其Path、RawQuery,同时清空原请求的查询参数,确保转发的请求完全使用目标URL的路径和参数。修正后的代码如下:

func handler(response http.ResponseWriter, request *http.Request) {
    // 解析原请求URL
    parsedURL, err := url.Parse(request.URL.String())
    if err != nil {
        http.Error(response, "Invalid request URL", http.StatusBadRequest)
        return
    }

    // 获取目标URL参数
    destinationURLStr := parsedURL.Query().Get("url")
    if destinationURLStr == "" {
        http.Error(response, "Missing 'url' parameter", http.StatusBadRequest)
        return
    }

    fmt.Println("Destination->", destinationURLStr)

    // 解析目标URL
    parsedDestinationURL, err := url.Parse(destinationURLStr)
    if err != nil {
        fmt.Printf("Error parsing destination URL: %s", err)
        http.Error(response, "Invalid destination URL", http.StatusBadRequest)
        return
    }

    fmt.Println("Parsed destination->", parsedDestinationURL)

    // 创建反向代理
    proxy := httputil.NewSingleHostReverseProxy(parsedDestinationURL)
    proxy.Transport = DebugTransport{}

    // 关键:替换request.URL的所有路径和参数为目标URL的内容
    request.URL.Scheme = parsedDestinationURL.Scheme
    request.URL.Host = parsedDestinationURL.Host
    request.URL.Path = parsedDestinationURL.Path
    request.URL.RawQuery = parsedDestinationURL.RawQuery // 直接用目标URL的原始查询参数

    // 移除原请求中带的url参数(避免残留)
    request.URL.Query().Del("url")

    // 设置转发头
    request.Header.Set("X-Forwarded-Host", request.Header.Get("Host"))
    request.Host = parsedDestinationURL.Host // 修正原代码的Host设置错误

    // 设置CORS
    response.Header().Set("Access-Control-Allow-Origin", "*")

    proxy.ServeHTTP(response, request)
}
关键改动说明
  1. 替换完整的URL路径与参数:直接将request.URL的Path和RawQuery设置为目标URL的对应值,彻底覆盖原请求的路径和参数,避免原请求的url参数被附带。
  2. 修正Host设置错误:原代码中request.Host = parsedURL.Host是错误的,应该设置为目标URL的Host,确保请求发送到正确的目标服务器。
  3. 增加错误处理:补充了URL解析失败、缺少url参数的错误处理,避免空指针或无效请求导致的崩溃。
  4. 移除原请求的url参数:双重保险,确保原请求中的url参数不会被带到转发请求中。

测试后,转发的请求会正确使用目标URL的路径和参数,不会再出现参数重复的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:06:47