Skip to content

Latest commit

 

History

History
108 lines (73 loc) · 5.02 KB

ContentNegotiation.md

File metadata and controls

108 lines (73 loc) · 5.02 KB

Content Negotiation

有时, 服务器应用程序需要在同一个URI上为资源的不同表示提供服务, 当然, 这可以手动完成, 手动检查 Accept 请求头并推送内容的请求形式, 然而, 当你的app控制更多的资源和不同类型的表示时, 这相当苦逼, 因为你可能需要检查 Accept-Charset , Accept-Encoding , 设置一些服务端优先级, 处理程序正确处理错误等等

在Go中有一些web框架已经在努力地实现这样的功能,但他们做得不对:

  • 根本不处理 Accept-Charset
  • 根本不处理 Accept-Encoding
  • 不会像RFC提议的那样发送错误状态码(406不可接受)等等

但是万幸, iris始终坚持最佳的实践效果和web标准

基于以下:

通过以下实现:

例子(Example)

type testdata struct {
    Name string `json:"name" xml:"Name"`
    Age  int    `json:"age" xml:"Age"`
}

用 "gzip" 编码算法将资源渲染为application/json 或者 text/xml 或者 application/xml

  • 当客户端的Accept头包含他们其中之一时
  • 或者JSON(第一个声明), 如果Accept为空时
  • 并且当客户端Accept-Encoding头包含 "gzip" 或者为空时
app.Get("/resource", func(ctx iris.Context) {
    data := testdata{
        Name: "test name",
        Age:  26,
    }

        ctx.Negotiation().JSON().XML().EncodingGzip()

    _, err := ctx.Negotiate(data)
    if err != nil {
        ctx.Writef("%v", err)
    }
})

或者在中间件中定义, 并在最终处理程序中协商为nil

ctx.Negotiation().JSON(data).XML(data).Any("content for */*")
ctx.Negotiate(nil)
app.Get("/resource2", func(ctx iris.Context) {
    jsonAndXML := testdata{
        Name: "test name",
        Age:  26,
    }

    ctx.Negotiation().
        JSON(jsonAndXML).
        XML(jsonAndXML).
        HTML("<h1>Test Name</h1><h2>Age 26</h2>")

    ctx.Negotiate(nil)
})

点我阅读所有例子

文档

Context.Negotiation方法会创建一次并且返回协商构建器, 来构建服务端特定的内容类型, 字符集和编码算法的可用优先级内容

Context.Negotiation() *context.NegotiationBuilder

Context.Negotiate方法用于在同一个URI上为资源的不同表示提供服务, 当未匹配到mime类型时,返回 context.ErrContentNotSupported

Context.Negotiate(v interface{}) (int, error)