为何url.ParseQuery方法返回结果不符合预期?如何修正?
URL查询参数解析结果不符的问题分析与解决
问题描述
给定的Go程序执行后输出结果为:{"x":["1 1 3"], "y":["2", "3"]}
但预期结果应为:{"x":["1+1+3"], "y":["2", "3"]}
原因
net/url包的ParseQuery函数遵循application/x-www-form-urlencoded编码规范,该规范中+符号会被解析为空格。所以当解析x=1+1+3时,字符串里的+会被自动替换成空格,导致最终x字段的值变成了1 1 3。
修改方案
方案一:解析后替换空格为+
在解析完成后,遍历url.Values中的所有值,将空格替换回+即可:
import ( "encoding/json" "fmt" "log" "net/url" "strings" ) func main() { m, err := url.ParseQuery(`x=1+1+3&y=2&y=3`) if err != nil { log.Fatal(err) } // 遍历替换每个值里的空格为+ for key, values := range m { updatedValues := make([]string, len(values)) for idx, val := range values { updatedValues[idx] = strings.ReplaceAll(val, " ", "+") } m[key] = updatedValues } fmt.Println(toJSON(m)) } func toJSON(m any) string { js, err := json.Marshal(m) if err != nil { log.Fatal(err) } return strings.ReplaceAll(string(js), ",", ", ") }
方案二:手动拆分并解码键值对
如果想避免ParseQuery自动替换+,可以手动拆分查询字符串,对每个值单独使用QueryUnescape处理(该函数不会将+替换为空格,只会解码%xx格式的转义字符):
import ( "encoding/json" "fmt" "log" "net/url" "strings" ) func main() { queryStr := `x=1+1+3&y=2&y=3` m := url.Values{} // 按&拆分每个键值对 for _, pair := range strings.Split(queryStr, "&") { kv := strings.SplitN(pair, "=", 2) if len(kv) != 2 { continue } key := kv[0] // 仅解码%xx转义,保留+ value, err := url.QueryUnescape(kv[1]) if err != nil { log.Fatal(err) } m.Add(key, value) } fmt.Println(toJSON(m)) } func toJSON(m any) string { js, err := json.Marshal(m) if err != nil { log.Fatal(err) } return strings.ReplaceAll(string(js), ",", ", ") }
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

