【问题标题】:Correct way to notify http client of error after partial response has been sent in golang http在golang http中发送部分响应后通知http客户端错误的正确方法
【发布时间】:2016-02-24 19:01:36
【问题描述】:

如果在向客户端写入流式响应时发生错误,http 服务器的正确行为是什么。客户端已经收到状态码 200,所以它认为没问题。服务器仍然可以终止连接以通知客户端发生错误还是应该在响应正文中返回某些内容?

我正在从数据库流式传输许多行,因此我不希望在发送到客户端之前进行批处理。

golang 中的一个例子:

func streamingHandler(s ServerSettings, db *sql.DB) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        w.Header().Set("Content-Type", "application/json-seq")

        w.Header().Set("Access-Control-Allow-Origin", "*")

        _, err = fmt.Fprintf(w, "\u001E[1,2,3]\n", item)

        if err != nil {
            http.Error(w, err.Error(), 500)
            return
        }

        _, err = fmt.Fprintf(w, "\u001E[1,2,3]\n", item)

        //  the error could be from Fprintf or a database error.

        //  What happens if error occurs here.. the client has already received header and some response

        if err != nil {
            http.Error(w, err.Error(), 500)
            return
        }
        ... 
        etc
    })

}

【问题讨论】:

  • 我不这么认为。您不能再发送任何标头。如果您确实预先指定了 Content-Length,那么至少应该清楚地表明响应是不完整的。否则客户端必须从内容本身推断。

标签: http go


【解决方案1】:

恐怕您必须在协议上添加一个协议。 就像使用 ajax 一样,使用您自己的 OK/Continue/Abort 状态消息发送简短的 json 响应。

HTTP 中没有任何东西可以处理(客户端到服务器中的 100-Continue 有一些东西,实施不当并且不是为服务器到客户端制作的),除非可能发送分块响应并且从不发送最后一个块(所以整个响应将超时)。

使用 ajax 解决方案,您还可以在结束之前开始显示结果。

在 HTTp 上管理您自己的块通常是最简单的解决方案,例如文件上传器,他们将使用 js 将文件分割成块并在服务器端重新组合文件。

尝试管理反向代理或代理可能在您的大型 HTTP 消息通信中注入的所有混乱(认为直到最近 Nginx 反向代理不会流式传输响应,并使用缓冲消息)。

【讨论】:

    猜你喜欢
    • 2017-05-29
    • 2015-09-24
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多