英文:
Google App Engine changes content-type to text/html even though it is set to application/xml
问题
这个问题之前已经有人问过了,但是那个答案适用于Python应用程序。我想知道如何解决Go应用程序的这个问题。
我在Google App Engine上部署了一个Web服务,被移动客户端使用。使用下面的函数,我根据客户端的请求将响应发送为XML或JSON格式:
func (api *API) Respond(w http.ResponseWriter, r *http.Request, body interface{}, status int) {
var contentType string
var content []byte
var err error
if r.Header.Get("Accept") == "application/xml" {
contentType = "application/xml; charset=UTF-8"
content, err = xml.Marshal(body)
} else {
contentType = "application/json; charset=UTF-8"
content, err = json.MarshalIndent(body, "", " ")
}
if err != nil {
panic(err)
}
w.WriteHeader(status)
w.Header().Set("Content-Type", contentType)
w.Write(content)
}
然而,在任何情况下,客户端设备都会收到text/html
的Content-Type。我该如何解决这个问题?这是我应用程序的app.yaml文件:
application: wks-api
version: 3
runtime: go
api_version: go1
handlers:
- url: /.*
script: api
英文:
This question has been asked before but that answer applies to python applications. I'd like to know how to fix the issue for go applications.
I've deployed a web service on Google App Engine which is consumed by mobile clients. Using the function below, I send the response either as XML or JSON (as requested by the client)
func (api *API) Respond(w http.ResponseWriter, r *http.Request, body interface{}, status int) {
var contentType string
var content []byte
var err error
if r.Header.Get("Accept") == "application/xml" {
contentType = "application/xml; charset=UTF-8"
content, err = xml.Marshal(body)
} else {
contentType = "application/json; charset=UTF-8"
content, err = json.MarshalIndent(body, "", " ")
}
if err != nil {
panic(err)
}
w.WriteHeader(status)
w.Header().Set("Content-Type", contentType)
w.Write(content)
}
In either case, however, the client device receives a Content-Type of text/html
. How can I fix this? Here's the app.yam file for my application:
application: wks-api
version: 3
runtime: go
api_version: go1
handlers:
- url: /.*
script: api
答案1
得分: 2
请看一下 https://golang.org/pkg/net/http/#ResponseWriter 中的文档,我引用一下:
> 在调用 WriteHeader(或 Write)之后更改标头没有效果
现在看一下你的代码:
w.WriteHeader(status)
w.Header().Set("Content-Type", contentType)
如你所见,你确实是在“调用 WriteHeader 之后更改标头”-- 因此,它“没有效果”。
所以,在这个调用之前,将你的“更改标头”操作放在前面:
w.Header().Set("Content-Type", contentType)
w.WriteHeader(status)
我认为这与应用引擎无关,它适用于 Go 中的任何使用 http
的情况。
英文:
Look at the documentation in https://golang.org/pkg/net/http/#ResponseWriter , and I quote:
> Changing the header after a call to WriteHeader (or Write) has no
> effect
Now look at your code:
w.WriteHeader(status)
w.Header().Set("Content-Type", contentType)
as you see, you are indeed "Changing the header after a call to WriteHeader" -- hence, it "has no effect".
So, do your "changing the header" before that call instead:
w.Header().Set("Content-Type", contentType)
w.WriteHeader(status)
I don't think this is at all specific to app engine -- it should apply to any use of http
in Go.
答案2
得分: 0
从http/header中获取信息:
> WriteHeader使用状态码发送HTTP响应头。如果没有显式调用WriteHeader,对Write的第一次调用将触发隐式的WriteHeader(http.StatusOK)。因此,显式调用WriteHeader主要用于发送错误代码。
首先尝试设置头部,然后发送它。
英文:
See information from http/header:
> 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.
first try settings the header then send it
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论