Golang API返回异常JSON格式但在浏览器中正常工作的解决方案

Golang API返回异常JSON格式但在浏览器中正常工作的解决方案 我之前处理过从API解析JSON数据,但现在在Go中获取到了奇怪的数据,而在浏览器中发起相同的API请求却能正常工作。

这是我使用的代码:

req, err := http.NewRequest("GET", "example.com", nil)
if err != nil {
    log.Fatalln("Failed to prepare API request")
}

client := &http.Client{Timeout: time.Second * 5}

// Make API request
request, err := client.Do(req)
if err != nil {
    log.Fatalln("Error requesting API")
}
defer request.Body.Close()

// Read API response
buf := new(bytes.Buffer)
buf.ReadFrom(request.Body)

log.Println(buf.String())

输出结果是一种我以前从未见过的非JSON风格:

({:previous_successful_build nil, :vcs-type :bitbucket, :canceler nil, :committer_name nil, :circle-yml nil, :infrastructure_fail false, :job-name nil, ...

如果我在浏览器中访问该API网址,我能看到正确的JSON格式:

2020-12-23_18-48-15

我的Go语言HTTP请求出了什么问题?

(我尝试在HTTP请求上设置 Application-Type 请求头,但没有效果。我当然也查看了网上的教程,但没发现我的代码有什么错误。)


更多关于Golang API返回异常JSON格式但在浏览器中正常工作的解决方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

Juk:

req

尝试添加一个请求头 req.Header.Add("Accept"," application/json")

如果没有API或服务器端逻辑,很难看出问题所在。

更多关于Golang API返回异常JSON格式但在浏览器中正常工作的解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢Eudore!我确实遗漏了 Accept 请求头。添加那一小行代码,就让一个无法工作的应用和一个几乎完成的应用之间产生了天壤之别。再次感谢你的帮助。

问题在于API返回的是Clojure风格的EDN格式,而不是标准的JSON。Go的encoding/json包无法解析这种格式。你需要使用EDN解析器来处理这种响应。

以下是解决方案:

package main

import (
    "bytes"
    "fmt"
    "log"
    "net/http"
    "time"
    
    "github.com/edn-format/edn-go" // 需要安装EDN解析库
)

func main() {
    req, err := http.NewRequest("GET", "https://example.com/api", nil)
    if err != nil {
        log.Fatalln("Failed to prepare API request:", err)
    }

    // 设置Accept头请求JSON格式(如果API支持)
    req.Header.Set("Accept", "application/json")
    
    client := &http.Client{Timeout: time.Second * 5}

    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln("Error requesting API:", err)
    }
    defer resp.Body.Close()

    // 读取响应
    buf := new(bytes.Buffer)
    buf.ReadFrom(resp.Body)
    rawResponse := buf.String()

    // 尝试解析为EDN
    var result map[string]interface{}
    err = edn.UnmarshalString(rawResponse, &result)
    if err != nil {
        log.Fatalf("Failed to parse EDN: %v\nRaw response: %s", err, rawResponse)
    }

    // 使用解析后的数据
    fmt.Printf("Parsed data: %+v\n", result)
    
    // 如果需要JSON,可以转换
    jsonBytes, _ := json.MarshalIndent(result, "", "  ")
    fmt.Printf("As JSON:\n%s\n", string(jsonBytes))
}

首先安装EDN解析库:

go get github.com/edn-format/edn-go

如果API支持多种格式,可以尝试设置Accept头来请求JSON:

req.Header.Set("Accept", "application/json")

如果API只返回EDN格式,你必须使用EDN解析器。浏览器能正常显示是因为它可能自动处理了格式转换,或者API根据User-Agent返回了不同格式。

检查API文档确认支持的格式,如果确实只返回EDN,那么EDN解析是必需的解决方案。

回到顶部