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
更多关于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设置。

