Golang请求在Postman或浏览器正常但代码中不生效怎么办

Golang请求在Postman或浏览器正常但代码中不生效怎么办 我是一个想成为Gopher的初学者…
在学习过程中遇到了一个奇怪的问题

在Postman或浏览器中发送HTTP GET请求是正常的(返回200 OK)
但在Golang中却不工作(返回404未找到)

我查阅了很多博客,他们说是CORS问题…
到底是什么问题呢?

以下是我的代码

req, err := http.NewRequest("GET", url_API, nil)
// url_API is https://1.1.1.1/api/?type=op&cmd=<show><rule-hit-count><vsys><vsys-name><entry name='vsys1'><rule-base><entry name='security'><rules><all/></rules></entry></rule-base></entry></vsys-name></vsys></rule-hit-count></show>&key=DSBMSKD83DSSFxO3fsdf#
if err != nil {
panic(err)
}
req.Header.Set("User-Agent", "Mozilla/5.0")
req.Header.Set("Content-Type", "application/xml")
req.Header.Set("Connection", "Keep-Alive")
req.Header.Set("Accept", "*/*")
req.Header.Set("Host", reqTarget)    // reqTarget is IP (ex. 1.1.1.1 and network device's mgmt ip)
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Cache-Control", "no-cache")

debug(httputil.DumpRequest(req, true))
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify : true},}
client := &http.Client{Transport: tr}
resp, err := client.Do(req)
if err != nil{
panic(err)
}
defer resp.Body.Close()

更多关于Golang请求在Postman或浏览器正常但代码中不生效怎么办的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

不是。这只是浏览器在尝试显示XML文档时的正常行为。

更多关于Golang请求在Postman或浏览器正常但代码中不生效怎么办的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


CORS问题通常不会导致404 Not Found响应。

当我改用 Chrome 浏览器而非 IE 运行时,收到以下信息:

此 XML 文件似乎没有关联任何样式信息。下方显示的是文档树状结构。

是否是因为这个原因?

由于您正在进行简单的 HTTP GET 请求,您可以在浏览器中轻松测试。如果您在浏览器中打开以下链接会发生什么?

https://1.1.1.1/api/?type=op&cmd=&key=DSBMSKD83DSSFxO3fsdf#

我从未尝试过使用 Go 语言,但我曾在 Node.js 和 JavaScript 中调用过 REST API。我遇到了同样的问题(CORS 策略:预检请求的响应未通过访问控制检查:没有 ‘Access-Control-Allow-Origin’ 头信息)。

但在 POSTMAN 中可以正常通过,而在代码中(使用 Node.js 或 JavaScript)却不行。

这个问题并非出在你这边,需要在服务器端进行修改。

你好 Iutzhorn, 200 OK 执行结果是 XML 格式…

<response status="success">
<result>
    <rule-hit-count>
        <vsys>
            <entry name="vsys1">
                <rule-base>
                    <entry name="security">
                        <rules>
                            <entry name="api_test">
                                <latest>yes</latest>
                                <hit-count>0</hit-count>
                                <last-hit-timestamp>0</last-hit-timestamp>
                                <last-reset-timestamp>0</last-reset-timestamp>
                                <first-hit-timestamp>0</first-hit-timestamp>
                            </entry>
                        </rules>
                    </entry>
                </rule-base>
            </entry>
        </vsys>
    </rule-hit-count>
</result>

浏览器中的请求头

Accept: text/html, application/xhtml+xml, image/jxr, / Accept-Encoding: gzip, deflate Accept-Language: ko-KR Connection: Keep-Alive Host: 1.1.1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

以及浏览器中的响应头

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: keep-alive Content-Length: 3904 Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘unsafe-eval’ ‘unsafe-inline’; style-src ‘self’ ‘unsafe-inline’; img-src ‘self’ data:; Content-Type: application/xml; charset=UTF-8 … Pragma: no-cache X-Content-Type-Options: nosniff X-FRAME-OPTIONS: SAMEORIGIN X-XSS-Protection: 1; mode=block

问题可能出在请求头设置上,特别是 Host 字段。在 Go 中手动设置 Host 头可能不会按预期工作,因为 Go 的 http 包会基于 URL 自动处理 Host 头。此外,URL 中的特殊字符(如 <>')需要正确编码,否则可能导致服务器返回 404。

首先,确保 URL 中的查询参数正确编码。使用 url.QueryEscapeurl.Values 来构建查询字符串。其次,移除手动设置的 Host 头,让 Go 自动处理。另外,检查 reqTarget 是否与 URL 中的主机匹配。

以下是修改后的代码示例:

package main

import (
    "crypto/tls"
    "fmt"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    // 原始 URL 中的查询参数需要编码
    baseURL := "https://1.1.1.1/api/"
    params := url.Values{}
    params.Set("type", "op")
    params.Set("cmd", "<show><rule-hit-count><vsys><vsys-name><entry name='vsys1'><rule-base><entry name='security'><rules><all/></rules></entry></rule-base></entry></vsys-name></vsys></rule-hit-count></show>")
    params.Set("key", "DSBMSKD83DSSFxO3fsdf#")
    
    fullURL := baseURL + "?" + params.Encode()
    
    req, err := http.NewRequest("GET", fullURL, nil)
    if err != nil {
        panic(err)
    }
    
    // 设置请求头,但移除 Host 头,让 Go 自动处理
    req.Header.Set("User-Agent", "Mozilla/5.0")
    req.Header.Set("Content-Type", "application/xml")
    req.Header.Set("Connection", "Keep-Alive")
    req.Header.Set("Accept", "*/*")
    req.Header.Set("Accept-Encoding", "gzip, deflate")
    req.Header.Set("Cache-Control", "no-cache")
    
    // 调试:打印请求详情
    debugReq, _ := httputil.DumpRequest(req, true)
    fmt.Printf("Request: %s\n", debugReq)
    
    // 配置 Transport 以跳过 TLS 验证(仅用于测试)
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
    
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    
    fmt.Printf("Response Status: %s\n", resp.Status)
}

关键修改:

  • 使用 url.ValuesEncode 方法正确编码查询参数,避免特殊字符导致 URL 无效。
  • 移除了手动设置的 Host 头,因为 Go 会根据 URL 自动设置。
  • 保留了其他头设置,如 User-Agent,以模拟浏览器行为。

如果问题仍然存在,检查服务器日志或使用工具(如 Wireshark)比较 Go 请求和 Postman 请求的原始数据,确认差异。CORS 通常影响浏览器中的跨域请求,但 Go 代码在服务器端运行,不受 CORS 限制,除非服务器有特殊验证。

回到顶部