Golang中如何处理GET请求返回的反斜杠问题

Golang中如何处理GET请求返回的反斜杠问题 你好,

我是Go语言的新手。我已经查阅了关于如何使 http.ResponseWriter 正常工作的文档。我构建了一个向API发送的GET请求,代码如下:

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/gomk/fixall/{server}", handler).Methods("GET")
	headers := handlers.AllowedHeaders([]string
        {"X-Requested-With", "Content-Type", "Authorization", 
        "access-control-allow-headers", "access-control-allow-methods",
         "access-control-allow-origin"})
	methods := handlers.AllowedMethods([]string
        {"GET", "POST", "PUT", "DELETE", "OPTIONS"})
	origins := handlers.AllowedOrigins([]string{"*"})

	fmt.Println("Server is running at port 8000")
	log.Fatal(http.ListenAndServe(":8000", handlers.CORS(headers, 
        methods, origins)(router)))
}

func handler(w http.ResponseWriter, r *http.Request) {
	params := mux.Vars(r)
	server := params["server"]
	resp, err := http.Get(`https://test.com/api/test&request={"hostname":"` 
    + params["server"] + `","mode":"test"}`)
	if err != nil {
		log.Fatalln(err)
		return
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln(err)
	}

	json.NewEncoder(w).Encode(string(body))
	fmt.Println(string(body))
}

这个调用确实在浏览器端口8000返回了正确的信息:但是,我在响应中得到了以下反斜杠:

"{\"result\": \"

而实际上应该是:

{"result": "

没有反斜杠的正确输出确实显示在控制台输出中。请问有人能帮我解释一下为什么我在浏览器中会得到这些反斜杠,以及什么样的配置能帮助我获得我想要的输出吗?


更多关于Golang中如何处理GET请求返回的反斜杠问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你JSON编码的是一个字符串,而不是一个对象。也许你应该直接按原样写入API返回的字符串?

更多关于Golang中如何处理GET请求返回的反斜杠问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的。我会调查一下。为了澄清我的帖子,目前我在控制台输出中确实收到了 {"result": "(没有反斜杠,刚刚修正了我的帖子)。

问题出在您对响应体的处理方式上。当您使用 json.NewEncoder(w).Encode(string(body)) 时,实际上是在对已经是JSON字符串的 body 进行二次JSON编码。

ioutil.ReadAll(resp.Body) 返回的是 []byte,当您将其转换为 string(body) 时,它已经是有效的JSON字符串。但 json.Encode() 会再次对其进行编码,将双引号等特殊字符转义为 \"

以下是两种解决方案:

方案1:直接写入响应(推荐)

func handler(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    resp, err := http.Get(`https://test.com/api/test&request={"hostname":"` + 
        params["server"] + `","mode":"test"}`)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    w.Write(body)
    
    fmt.Println(string(body))
}

方案2:如果确实需要解码再编码

func handler(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    resp, err := http.Get(`https://test.com/api/test&request={"hostname":"` + 
        params["server"] + `","mode":"test"}`)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(result)
    
    fmt.Printf("%+v\n", result)
}

关键点:

  1. 方案1直接传递原始JSON响应,避免二次编码
  2. 方案2先解码为Go数据结构,再重新编码为JSON
  3. 设置正确的Content-Type头:application/json
  4. 使用 http.Error() 替代 log.Fatalln() 来返回错误响应

控制台输出正常是因为 fmt.Println(string(body)) 直接打印原始字符串,而浏览器接收的是经过 json.Encode() 处理后的转义JSON字符串。

回到顶部