Http 为什么我在更改用户代理时被拒绝?

Http 为什么我在更改用户代理时被拒绝?,http,go,request,Http,Go,Request,我有一个从nike.com获取robots.txt文件的简单请求。Go中的正常GET请求按预期返回文件。在我当前的浏览器中,我可以很好地访问文件。然而,当我尝试将我的UA更改为与浏览器相同时,我得到了403错误 换句话说,我可以使用Go中的默认设置访问页面,证明我的代码是正确的,但一旦我更改UA,我会得到403,即使我的浏览器中的UA也可以 如果我将UA更改为随机值,例如不是我,则我得到200分。为什么我不能使用浏览器的UA package main import ( "log"

我有一个从nike.com获取robots.txt文件的简单请求。Go中的正常GET请求按预期返回文件。在我当前的浏览器中,我可以很好地访问文件。然而,当我尝试将我的UA更改为与浏览器相同时,我得到了403错误

换句话说,我可以使用Go中的默认设置访问页面,证明我的代码是正确的,但一旦我更改UA,我会得到403,即使我的浏览器中的UA也可以

如果我将UA更改为随机值,例如不是我,则我得到200分。为什么我不能使用浏览器的UA

package main

import (
    "log"
    "net/http"

    "github.com/davecgh/go-spew/spew"
)

func main() {
    var resp *http.Response
    var err error
    u := "http://www.nike.com/robots.txt"

    for _, ua := range []bool{false, true} {
        client := &http.Client{}
        req, _ := http.NewRequest("GET", u, nil)
        if ua == true {
            req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36")
        }
        resp, err = client.Do(req)
        if err != nil {
            log.Fatalln(err)
        }
        log.Println("StatusCode", resp.StatusCode)
        spew.Dump(resp.Request)
        log.Println("----------------------------")
    }

}
答复如下:

2016/06/22 16:56:57 StatusCode 200
(*http.Request)(0xc8200d02a0)({
 Method: (string) (len=3) "GET",
 URL: (*url.URL)(0xc820076280)(http://www.nike.com/robots.txt),
 Proto: (string) (len=8) "HTTP/1.1",
 ProtoMajor: (int) 1,
 ProtoMinor: (int) 1,
 Header: (http.Header) {
 },
 Body: (io.ReadCloser) <nil>,
 ContentLength: (int64) 0,
 TransferEncoding: ([]string) <nil>,
 Close: (bool) false,
 Host: (string) (len=12) "www.nike.com",
 Form: (url.Values) <nil>,
 PostForm: (url.Values) <nil>,
 MultipartForm: (*multipart.Form)(<nil>),
 Trailer: (http.Header) <nil>,
 RemoteAddr: (string) "",
 RequestURI: (string) "",
 TLS: (*tls.ConnectionState)(<nil>),
 Cancel: (<-chan struct {}) <nil>
})
2016/06/22 16:56:57 ----------------------------
2016/06/22 16:56:57 StatusCode 403
(*http.Request)(0xc820110000)({
 Method: (string) (len=3) "GET",
 URL: (*url.URL)(0xc8200ea180)(http://www.nike.com/robots.txt),
 Proto: (string) (len=8) "HTTP/1.1",
 ProtoMajor: (int) 1,
 ProtoMinor: (int) 1,
 Header: (http.Header) (len=1) {
  (string) (len=10) "User-Agent": ([]string) (len=1 cap=1) {
   (string) (len=104) "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36"
  }
 },
 Body: (io.ReadCloser) <nil>,
 ContentLength: (int64) 0,
 TransferEncoding: ([]string) <nil>,
 Close: (bool) false,
 Host: (string) (len=12) "www.nike.com",
 Form: (url.Values) <nil>,
 PostForm: (url.Values) <nil>,
 MultipartForm: (*multipart.Form)(<nil>),
 Trailer: (http.Header) <nil>,
 RemoteAddr: (string) "",
 RequestURI: (string) "",
 TLS: (*tls.ConnectionState)(<nil>),
 Cancel: (<-chan struct {}) <nil>
})
2016/06/22 16:56:57 ----------------------------
编辑:
我已经玩了一会儿,如果我设置了Chrome发送的所有其他头,那么它就会工作。

您的测试代码使用相同的HTTP客户端对象发送两个请求,这两个请求可能都通过相同的连接


您是否尝试通过不同的连接发送请求?尝试将您的标志设置为true然后设置为false,看看是否总是第二个失败。

您的测试代码使用相同的HTTP客户端对象发送两个请求,这两个请求可能都经过相同的连接


您是否尝试通过不同的连接发送请求?尝试将您的标志设置为true然后设置为false,看看是否总是第二个失败。

有趣!Chrome的用户代理给出403。chrome的用户代理给出200。也许耐克认为你在试图模仿浏览器?很有趣!Chrome的用户代理给出403。chrome的用户代理给出200。也许耐克认为你在试图模仿浏览器?我试着在没有运气的情况下切换顺序。我已经玩了一点,如果我设置了Chrome发送的所有其他标题,那么它就可以工作了。想知道耐克为什么这么做…@kristen:该网站正试图阻止恶意活动。如果它知道你不是一个chrome浏览器,但得到了一个chrome用户代理,它将拒绝这个请求。这是我的下一个建议——查看所有其他标题。一定有什么指纹在那里。UA字符串在不同的客户端之间看起来非常相似是很常见的。@JimB:这很有道理。我发疯了,想看看是不是围棋里有什么虫子。这似乎不是防止任何事情发生的好方法,因为即使像我这样的业余爱好者最终也会发现,设置其余的标题可以让我欺骗一个真正的浏览器。@kristen:我没说它很擅长这样做;它最有可能是一个应用程序防火墙,根据其通过akamai边缘服务器的先前模式,对每个请求应用各种试探法。如果您要使用不同的特定样式的头导致问题,您可能会发现它也被阻塞了。不管怎样,行为完全取决于远程服务器。我尝试在没有运气的情况下切换顺序。我已经玩了一点,如果我设置了Chrome发送的所有其他标题,那么它就可以工作了。想知道耐克为什么这么做…@kristen:该网站正试图阻止恶意活动。如果它知道你不是一个chrome浏览器,但得到了一个chrome用户代理,它将拒绝这个请求。这是我的下一个建议——查看所有其他标题。一定有什么指纹在那里。UA字符串在不同的客户端之间看起来非常相似是很常见的。@JimB:这很有道理。我发疯了,想看看是不是围棋里有什么虫子。这似乎不是防止任何事情发生的好方法,因为即使像我这样的业余爱好者最终也会发现,设置其余的标题可以让我欺骗一个真正的浏览器。@kristen:我没说它很擅长这样做;它最有可能是一个应用程序防火墙,根据其通过akamai边缘服务器的先前模式,对每个请求应用各种试探法。如果您要使用不同的特定样式的头导致问题,您可能会发现它也被阻塞了。无论如何,行为完全取决于远程服务器。