为什么我不能在HTTP重定向中添加正文?

huangapple go评论79阅读模式
英文:

Why can't I add a body to an http redirect?

问题

这是我尝试过的代码:

w.WriteHeader(301)
w.Write([]byte("重定向中..."))
w.Header().Set("Location", "/myredirecturl")
w.Header().Set("Content-Length", contentLength) // 我以为这样会有帮助

由于某种奇怪的原因,它不会添加Location头。为什么无法在golang的http包中同时添加正文和重定向?

英文:

Here is what I've tried:

w.WriteHeader(301)
w.Write([]byte("Redirecting..."))
w.Header().Set("Location", "/myredirecturl")
w.Header().Set("Content-Length", contentLength) // I thought this might help

It won't add the Location header for some odd reason.
Why isn't it possible to add a body and redirect golang's http package?

答案1

得分: 5

这在net/http包中有详细说明:

type ResponseWriter

type ResponseWriter interface {
    // Header返回将由WriteHeader发送的头映射。
    // 在调用WriteHeader(或Write)之后更改头部不会产生效果。
    Header() Header

    // Write将数据作为HTTP回复的一部分写入连接。
    // 如果尚未调用WriteHeader,则Write在写入数据之前调用WriteHeader(http.StatusOK)。
    // 如果Header不包含Content-Type行,则Write将Content-Type添加为将初始512字节写入数据传递给DetectContentType的结果。
    Write([]byte) (int, error)

    // WriteHeader使用状态码发送HTTP响应头。
    // 如果未显式调用WriteHeader,则对Write的第一次调用将触发隐式的WriteHeader(http.StatusOK)。
    // 因此,显式调用WriteHeader主要用于发送错误代码。
    WriteHeader(int)
}

上述内容说明在调用Write()WriteHeader()之后无法更改Header()。你应该将代码更改为以下形式:

w.Header().Set("Location", "/myredirecturl")
w.WriteHeader(301)
w.Write([]byte("Redirecting..."))
英文:

This is documented in the net/http package:
> ### type ResponseWriter
>
> type ResponseWriter interface {
> // Header returns the header map that will be sent by WriteHeader.
> // Changing the header after a call to WriteHeader (or Write) has
> // no effect.
> Header() Header
>
> // Write writes the data to the connection as part of an HTTP reply.
> // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
> // before writing the data. If the Header does not contain a
> // Content-Type line, Write adds a Content-Type set to the result of passing
> // the initial 512 bytes of written data to DetectContentType.
> Write([]byte) (int, error)
>
> // WriteHeader sends an HTTP response header with status code.
> // If WriteHeader is not called explicitly, the first call to Write
> // will trigger an implicit WriteHeader(http.StatusOK).
> // Thus explicit calls to WriteHeader are mainly used to
> // send error codes.
> WriteHeader(int)
> }

The above states that you cannot change Header() after a call to Write() or WriteHeader(). You should change your code to the following:

w.Header().Set("Location", "/myredirecturl")
w.WriteHeader(301)
w.Write('Redirecting...')

答案2

得分: 3

问题在于一旦调用Write或WriteHeader方法,响应头就会被发送到客户端。在此之后设置的任何头部都会被忽略。所以只需改变命令的顺序即可解决这个问题:

w.Header().Set("Location", "/myredirecturl")
w.Header().Set("Content-Length", contentLength) // 我认为这可能会
w.WriteHeader(301)
w.Write('Redirecting...')
英文:

The problem is that once you call Write or WriteHeader, the headers get flushed to the client. Anything headers set after that will get ignored. So just changing the order of commands will fix this:

w.Header().Set("Location", "/myredirecturl")
w.Header().Set("Content-Length", contentLength) // I thought this might 
w.WriteHeader(301)
w.Write('Redirecting...')

huangapple
  • 本文由 发表于 2015年5月23日 02:57:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/30404024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定