Golang发送HTTP GET请求返回400,curl请求正常,求助解决
问题分析与解决
问题原因
你在Golang代码中错误地对整个URL执行了url.QueryUnescape操作:
decodedUrl, err := url.QueryUnescape(originUrl)
这个操作会把URL里所有URL编码字符(比如%20)解码为原始字符(空格),而HTTP标准中,URL的查询参数不允许直接包含空格,服务器收到包含空格的请求后会判定为无效请求,返回400 Bad Request。
而curl请求直接使用了原始的URL编码字符串,没有做解码操作,因此服务器能正确识别请求参数,返回200。
解决方案
方案1:直接使用原始URL发起请求
去掉不必要的QueryUnescape步骤,直接用原始URL调用http.Get即可:
func TestParseUrl(t *testing.T) { originUrl := "https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fexplorer.api.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&state=I_b9zgmBonH9_nyKm3pF45sBPZeYhEIVdYNduPXP1KU&code_challenge=DjrdWVogz4KP6iQtmtbByQzqeFIO0_rckquiiEwCgxc&code_challenge_method=S256" // 直接发送请求,无需解码整个URL response, err := http.Get(originUrl) if err != nil { fmt.Println("send failure:", err) return } defer response.Body.Close() fmt.Println(response.Status) }
方案2:如需修改查询参数,正确解析并重构URL
如果后续需要修改URL中的查询参数,应该先解析URL结构,单独处理参数再重新构建完整URL,示例如下:
func TestParseUrl(t *testing.T) { originUrl := "https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fexplorer.api.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&state=I_b9zgmBonH9_nyKm3pF45sBPZeYhEIVdYNduPXP1KU&code_challenge=DjrdWVogz4KP6iQtmtbByQzqeFIO0_rckquiiEwCgxc&code_challenge_method=S256" // 解析URL结构 parsedUrl, err := url.Parse(originUrl) if err != nil { fmt.Println("parse url err:", err) return } // 获取并解码查询参数(仅解码参数值,而非整个URL) queryParams := parsedUrl.Query() // 示例:修改state参数 queryParams.Set("state", "new_custom_state_value") // 重新编码并设置查询参数 parsedUrl.RawQuery = queryParams.Encode() // 发送请求 response, err := http.Get(parsedUrl.String()) if err != nil { fmt.Println("send failure:", err) return } defer response.Body.Close() fmt.Println(response.Status) }
关键说明
url.QueryUnescape仅适用于解码单个查询参数的值,不能直接作用于整个URL。- HTTP请求的URL必须保持正确的编码格式,特殊字符(如空格、&、=等)需要通过URL编码转义,服务器才能正确解析。
内容的提问来源于stack exchange,提问作者Bai
相关产品推荐
相关产品推荐

