英文:
go properly handling slices and strings
问题
我正在使用goRequest(http://parnurzeal.github.io/gorequest/)来对一个我需要通信的服务器进程进行一些HTTP请求。身份验证过程如下:
发送一个带有身份验证头的GET请求。没有问题,但是我需要从响应中获取一个头,并使用返回的值重新验证每个后续请求。
返回的HTTP头看起来像这样。
响应头
map[Location:[900767244] Content-Type:[application/xml] Date:[Fri, 18 Sep 2015 18:19:41 GMT] Server:[Apache] X-Frame-Options:[SAMEORIGIN] Set-Cookie:[JSESSIONID=D5C976F5646365FF030DBAD770DA774C; Path=/; Secure; HttpOnly]]
我需要获取那个位置值,因为它是我未来的会话令牌。如果我这样获取它:
session, ok := response.Header["Location"]
if !ok {
fmt.Println("Did not receive a location header.")
}
fmt.Println("Session: ", session)
我可以得到它,但它是一个切片而不是字符串。我该如何将该值作为字符串获取,以便我可以将其放回我的请求头中?正如您在以下错误中看到的:
./login.go:133: cannot use session (type []string) as type string in argument to logoutRequest.Delete
非常感谢!
Craig
英文:
I am using goRequest http://parnurzeal.github.io/gorequest/ to make some HTTP requests against a server process I need to talk to. The authentication process works like this;
send in a GET request with an authentication header set. No problem there, but I need to grab a header from the response and use a returned value to reauthenticate each following request.
The retuned HTTP header looks like this.
Response headers
map[Location:[900767244] Content-Type:[application/xml] Date:[Fri, 18 Sep 2015 18:19:41 GMT] Server:[Apache] X-Frame-Options:[SAMEORIGIN] Set-Cookie:[JSESSIONID=D5C976F5646365FF030DBAD770DA774C; Path=/; Secure; HttpOnly]]
I need to get that location value as it's my session token going forward. If I grap it like this:
session, ok := response.Header["Location"]
if !ok {
fmt.Println("Did not receive a location header.")
}
fmt.Println("Session: ", session)
I can get it, but it's a slice and NOT a string. How can I get that value as a string so I can pop it back into my request headers going forward? As you can see in the following error:
./login.go:133: cannot use session (type []string) as type string in argument to logoutRequest.Delete
Thanks a lot!
Craig
答案1
得分: 1
如果你只想获取一个值,可以使用Header的Get方法
location := response.Header.Get("Location")
这个方法还会为你规范化头部名称,这样即使使用了稍微不同的大小写,你仍然可以得到一个值。
只有当你需要获取多个可能的值时,才需要直接索引http.Header
的值。如果你想要所有具有规范化头部名称的值,你可以使用textproto.CanonicalMIMEHeaderKey
vals := response.Header[textproto.CanonicalMIMEHeaderKey(header)]
英文:
If you want one value, use the Header's Get method
location := response.Header.Get("Location")
This also canonicalizes the header name for you, so that you still get a value even when using slightly different capitalization.
You only need to index an http.Header
value directly when you need to get more than than the first possible value. If you want all values with a canonicalized header name, you can use textproto.CanonicalMIMEHeaderKey
vals := response.Header[textproto.CanonicalMIMEHeaderKey(header)]
答案2
得分: 0
头部信息中的位置是一个数组,你只需要将Location[0]
传递给该方法,而不是简单地传递Location
,因为它是一个切片。话虽如此,未经检查地对数组进行索引是不安全的,所以你应该做如下判断:
if len(Location) == 1 {
logoutRequest(Location[0])
} else {
// 错误状态
}
最后,为了给你提供未来的指导,你可以通过观察响应头对象的类型更像是这样的:map[string][]string
(实际上可能是[]interface{}
,但我不能确定输出的情况),通过看到外部方括号[]
中的每个项都包含在另一组方括号中,这意味着它是一个可能包含0个或多个值的数组。
英文:
The headers have location as an array, you just need to pass Location[0]
to that method rather than simply Location
because it is a slice. That being said, indexing into the array without checking the bounds is unsafe so you should probably do;
if len(Location) == 1 {
logoutRequest(Location[0])
} else {
// error state
}
One last thing to provide you guidance in the future. You can tell that the response headers object has a type more like this; map[string][]string
(in reality that maybe []interface{} but I'm not certain from the output) by seeing that each item inside the outer brackets []
has it's values contained within another set of brackets, meaning it is an array that could contain 0 or more values.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论