解决Golang WriteHeader设置后,Content-Type失效的问题

场景

最近笔者在研究web框架过程中,发现了一个响应类型的问题,困扰许久,原因就是设置了响应状态码后,然后设置响应类型为application/json。在实际请求后,响应类型变成了text/plain; charset=utf-8格式。

在这里插入图片描述
在这里插入图片描述

问题解决:

先设置请求头的Content-type属性,再设置响应状态码,即可解决问题

// 例如:
func writeContentType(w http.ResponseWriter) {header := w.Header()if val := header["Content-Type"]; len(val) == 0 {header["Content-Type"] = []string{"application/json; charset=utf-8"}}
}
// 先执行
writeContentType(w)
// 再执行
w.WriteHeader(code)

分析导致问题的原因

我们处理请求接收的参数是:http.ResponseWriter类型的,它是一个接口类型,只要实现了这个接口都可以作为参数传递进来。

而实际传递进来的是:response结构体,它实现了http.ResponseWriter接口

可以通过定位http.ResponseWriter结构体,在同文件里面找到response结构体

我们查看一下response结构体的WriteHeader方法的源码,里面有一段代码:

func (w *response) WriteHeader(code int) {// 忽略代码if w.calledHeader && w.cw.header == nil {w.cw.header = w.handlerHeader.Clone()}// 忽略代码
}  

再看一下response结构体的Header方法(因为我们实际就是调用它,然后设置响应头的):

func (w *response) Header() Header {if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {w.cw.header = w.handlerHeader.Clone()}w.calledHeader = truereturn w.handlerHeader
}

总结问题:

通过分析上面两组代码可以发现,如果我们先执行了WriteHeader方法,它会给w.cw.header设置值,此时我们再调用Header方法设置Content-type属性时,经过if判断,w.cw.header并不等于nil了,所以我们给header设置的属性无法设置到w.cw.header上面,导致实际响应时,content-type发生变化。关键点就在于w.cw.header这个字段,如果设置的属性没到它上面的话,会导致失效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/315765.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RPA 培训前期准备指南——安装Uibot(RPA设计软件)

目录 一、电脑环境要求 二、所需的软件 2.1 办公软件 Office 版本: 2.2 Chrome 谷歌浏览器: 2.3 钉钉软件:官网下载 2.4 UiBot Creator 机器人流程自动化软件及 Chrome 扩展 三、UiBot Creator 安装与注册说明 (1&#xf…

公网ip数字证书申请流程

SSL数字证书是一种安全通信协议,它使用加密技术来保护在网络上传输的数据的机密性和完整性。当一个网站使用SSL数字证书时,它可以在浏览器和网站之间建立一条加密通道,确保用户在网站上输入的信息,如用户名、密码、信用卡信息等&a…

Halcon顶帽运算top_hat

Halcon顶帽运算 顶帽运算的原理是用原始的二值图像减去开运算的图像。开运算的目的是“移除”某些局部像素,如去毛边、断开相邻的边缘等。而顶帽运算正是用来提取这些被移除的部分。图(a)为从二值图像中提取出的亮的区域,可见有一…

什么?想学Go语言的人有福了?

最新好多小伙伴想学习云原生,但是都不知道怎么去学,我建议他们先去学一下G语言,作为云原生基础语言。 但是告诉我说找不到Go语言学习资料??? 好嘛,我连夜整理了几十本Go语言学习的pdf资料&…

【C#】知识点实践序列之Lock简单解决并发引起数据重复问题

欢迎来到《小5讲堂之知识点实践序列》文章,大家好,我是全栈小5。 这是2024年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正! 本篇在Lock锁定代码块基…

.NET DevOps 接入指南 | 1. GitLab 安装

引言 容器、DevOps和微服务被称为驱动云原生快速发展的三架马车。而DevOps是其中非常重要的一环,DevOps 是由Developers(Dev)和Operations(Ops)两个单词简称组成,中文直译就是“开发运维一体化”。 DevOps…

SpringBoot+SSM项目实战 苍穹外卖(08) 用户下单支付 内网穿透cpolar软件 绕开微信支付实现

继续上一节的内容,本节导入地址簿功能代码,并实现用户下单和订单支付功能。 这里写目录标题 导入地址簿功能代码接口分析代码实现 用户下单接口分析代码实现 订单支付内网穿透——cpolar软件代码导入绕开微信支付实现 导入地址簿功能代码 地址簿&#x…

12.31信号位宽转换(整数,非整数),时钟分频(奇数,偶数,任意小数,占空比),自动售货机(1,2),游戏机

非整数倍数据位宽转换8to12 所谓非整数倍,就是利用一个cnt去周期性决定寄存器里怎么输出,这个cnt的值,是最小公倍数 寄存器就正常的寄存,怎么输入怎么寄存 timescale 1ns/1nsmodule width_8to12(input clk , input…

STM32L4

STM32L4系列超低功耗微控制器 意法半导体通过构建新型芯片架构实现了同类产品中最佳的超低功耗及性能,这得益于应用设计上的高度灵活性。 STM32L4系列可以根据微处理器运行时不同的应用需求来适时调整电压从而实现功耗的动态平衡。 该系列包含不同的产品线&#…

基于Java (spring-boot)的在线培训考试系统

一、项目介绍 在线培训系统是一款基于SpringBootVue开发的考试系统。一款多角色在线培训考试系统,系统集成了用户管理、角色管理、部门管理、题库管理、试题管理、试题导入导出、考试管理、在线考试、错题训练等功能,考试流程完善。 多角色:多…

docker 部署教学版本

文章目录 一、docker使用场景及常用命令1)docker使用场景2)rocky8(centos8)安装 docker3)docker 常用命令补充常用命令 二、 单独部署每个镜像,部署spring 应用镜像推荐(2023-12-18)1、 安装使用 mysql1.1 …

虚幻UE 材质-边界混合之PDO像素深度偏移量

2024年的第一天!!!大家新年快乐!!! 可能是长大了才知道 当你过得一般 你的亲朋好友对你真正态度只可能是没有表露出来的冷嘲热讽了 希望大家新的一年平安、幸福、 永远活力满满地追求自己所想做的、爱做的&…