Golang调用API时遇到错误:http: server gave HTTP response to HTTPS client

Golang调用API时遇到错误:http: server gave HTTP response to HTTPS client 我正在使用Go语言调用谷歌地图地理编码API,但一直遇到这个错误:

HTTP请求失败,错误信息:Get https://maps.googleapis.com/maps/api/geocode/json?address=Bangalore&key=KEY: http: 服务器向HTTPS客户端返回了HTTP响应

错误中的URL在浏览器中可以正常访问并返回正确响应,但在以下代码片段中无法实现预期效果:

package main

import(
    "fmt"
    "io/ioutil"
    "net/http"
)

func main()  {
    key := "mysecretkey"
    location := "Bangalore"
    url := "https://maps.googleapis.com/maps/api/geocode/json?address="+location+"&key="+key
    fmt.Println("Starting the application...")
    response, err := http.Get(url)

    if err!=nil{
        fmt.Printf("The HTTP request failed with error %s\n", err)
    }else {
        data, _ := ioutil.ReadAll(response.Body)
        fmt.Println(string(data))
    }
}

奇怪的是,当我在repl.it(在线编程平台)上运行相同代码时,却能正常运行。我当前使用的是Go 1.9.3版本。


更多关于Golang调用API时遇到错误:http: server gave HTTP response to HTTPS client的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang调用API时遇到错误:http: server gave HTTP response to HTTPS client的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这个错误通常表示服务器端返回了HTTP响应,但客户端期望的是HTTPS响应。在Go语言中,这可能由多种原因导致,包括代理设置、网络配置或服务器重定向问题。

以下是几种解决方案:

方案1:使用自定义HTTP客户端并禁用安全验证

package main

import(
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    key := "mysecretkey"
    location := "Bangalore"
    url := "https://maps.googleapis.com/maps/api/geocode/json?address="+location+"&key="+key
    
    // 创建自定义Transport,跳过证书验证
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    
    client := &http.Client{Transport: tr}
    
    fmt.Println("Starting the application...")
    response, err := client.Get(url)

    if err != nil {
        fmt.Printf("The HTTP request failed with error %s\n", err)
    } else {
        data, _ := ioutil.ReadAll(response.Body)
        fmt.Println(string(data))
        response.Body.Close()
    }
}

方案2:检查并处理重定向

package main

import(
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

func main() {
    key := "mysecretkey"
    location := "Bangalore"
    urlStr := "https://maps.googleapis.com/maps/api/geocode/json?address="+location+"&key="+key
    
    client := &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            // 检查重定向URL是否为HTTPS
            if req.URL.Scheme != "https" {
                return fmt.Errorf("unsafe redirect from https to http")
            }
            return nil
        },
    }
    
    req, err := http.NewRequest("GET", urlStr, nil)
    if err != nil {
        fmt.Printf("Error creating request: %s\n", err)
        return
    }
    
    fmt.Println("Starting the application...")
    response, err := client.Do(req)

    if err != nil {
        fmt.Printf("The HTTP request failed with error %s\n", err)
    } else {
        data, _ := ioutil.ReadAll(response.Body)
        fmt.Println(string(data))
        response.Body.Close()
    }
}

方案3:使用URL编码参数

package main

import(
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

func main() {
    key := "mysecretkey"
    location := "Bangalore"
    
    // 使用url.Values正确编码参数
    params := url.Values{}
    params.Add("address", location)
    params.Add("key", key)
    
    urlStr := "https://maps.googleapis.com/maps/api/geocode/json?" + params.Encode()
    
    fmt.Println("Request URL:", urlStr)
    fmt.Println("Starting the application...")
    
    response, err := http.Get(urlStr)

    if err != nil {
        fmt.Printf("The HTTP request failed with error %s\n", err)
    } else {
        data, _ := ioutil.ReadAll(response.Body)
        fmt.Println(string(data))
        response.Body.Close()
    }
}

方案4:完整的错误处理和调试

package main

import(
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "crypto/tls"
)

func main() {
    key := "mysecretkey"
    location := "Bangalore"
    
    params := url.Values{}
    params.Add("address", location)
    params.Add("key", key)
    
    urlStr := "https://maps.googleapis.com/maps/api/geocode/json?" + params.Encode()
    
    // 创建自定义客户端
    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: false, // 生产环境应为false
            },
        },
    }
    
    req, err := http.NewRequest("GET", urlStr, nil)
    if err != nil {
        fmt.Printf("Error creating request: %s\n", err)
        return
    }
    
    req.Header.Set("User-Agent", "Go-API-Client/1.0")
    
    fmt.Println("Starting the application...")
    response, err := client.Do(req)

    if err != nil {
        fmt.Printf("The HTTP request failed with error %s\n", err)
        // 检查错误类型
        if urlErr, ok := err.(*url.Error); ok {
            fmt.Printf("URL Error: %v\n", urlErr)
        }
    } else {
        defer response.Body.Close()
        
        fmt.Printf("Response Status: %s\n", response.Status)
        fmt.Printf("Response Headers: %v\n", response.Header)
        
        data, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("Error reading response: %s\n", err)
            return
        }
        
        fmt.Println("Response Body:")
        fmt.Println(string(data))
    }
}

建议首先尝试方案3,因为它正确处理了URL参数编码,这是API调用中常见的问题源。如果问题仍然存在,再尝试方案1中的自定义Transport设置。

回到顶部