Go HTTP服务循环返回多文件处理结果报WriteHeader重复调用错误如何解决
问题解决方法
核心原因
HTTP协议的响应状态码、响应头仅允许在返回响应体之前写入1次,你在循环中重复调用w.WriteHeader和重复设置响应头就会触发报错。之前移除WriteHeader后返回纯文本,是因为你把Content-Type设置也放在了循环内,第一次写入响应体时Go自动触发WriteHeader(200),此时还未执行到后续的Header.Set,导致Content-Type被自动识别为纯文本。
修改方案
将响应头设置、状态码写入操作移到循环外仅执行1次,同时通过http.Flusher主动刷新缓冲实现实时推送,采用JSON Lines格式分隔多个处理结果:
// 先完成所有响应配置,仅执行1次 w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) // 断言获取Flusher接口,用于实时刷新响应缓冲 flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "server does not support streaming response", http.StatusInternalServerError) return } // 循环处理文件,仅写入响应体 for i, file := range files { uniqueSlice := unique(matches) output = Output{MSG: "ok", File: file, Skills: uniqueSlice} data, err := json.Marshal(output) if err != nil { panic(err) } // 追加换行符分隔不同文件的JSON结果,符合JSON Lines规范 data = append(data, '\n') _, err = w.Write(data) if err != nil { // 写入失败(如客户端断开连接)直接终止处理 return } // 立即刷新缓冲,将当前结果推送给客户端 flusher.Flush() }
配套客户端处理要求
客户端不能将整个响应作为单个JSON对象解析,需要按流逐行读取,每行对应一个文件的处理结果单独解析即可。
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

