Google App Engine将内容类型更改为text/html,即使它被设置为application/xml。

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

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

huangapple
  • 本文由 发表于 2015年11月27日 16:12:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/33952908.html
匿名

发表评论

匿名网友

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

确定