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

news2024/7/6 18:53:20

场景

最近笔者在研究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 = true
	return 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.coloradmin.cn/o/1350852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis安装与配置(Ubuntu)

目录 1. 切换到 root 用户 2. 搜索安装包 3. 安装 redis 4. 查看 redis 是否正常存在 5. 修改ip 6. 重新启动服务器 7. 连接服务器 1. 切换到 root 用户 通过 su 命令切换到 root 用户。 2. 搜索安装包 apt search redis 这里安装的是下面的版本: 3. 安装 …

三、C语言中的分支与循环—while循环 (5)

本章分支结构的学习内容如下: 三、C语言中的分支与循环—if语句 (1) 三、C语言中的分支与循环—关系操作符 (2) 三、C语言中的分支与循环—条件操作符 与逻辑操作符(3) 三、C语言中的分支与循环—switch语句(4)分支结构 完 本章循环结…

2024.1.1力扣每日一题——经营摩天轮的最大利润

2024.1.1 题目来源我的题解方法一 模拟 题目来源 力扣每日一题;题序:1599 我的题解 方法一 模拟 计算当前上摩天轮的人数和等待的人数就可以得到该轮次的利润,然后一只更新最大利润就可以了。 时间复杂度:O(n)。n数组的长度 空…

关于LayUI表格重载数据问题

目的 搜索框搜索内容重载数据只显示搜索到的结果 遇到的问题 在layui官方文档里介绍的table属性有data项,但使用下列代码 table.reload(test, {data:data //data为json数据}); 时发现,会会重新调用table.render的url拿到原来的数据,并不会显示出来传…

DDoS 攻击并不是全部来自于PC组成的僵尸网络

DDoS,分布式拒绝服务攻击,是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。很多人会以为DDoS 攻击,全都是攻击者控制PC肉鸡发起的攻击…

Android Studio xml布局代码补全功能失效问题

这里写目录标题 前言:问题描述原因分析:解决方案:1.更新 Android Studio 版本2.原版本解决XML补全失效 小结 前言: 在开发过程中,你可能遇到很多奇奇怪怪的问题。Android Studio 编译器出现问题也是常有的事情&#x…

2 Windows网络编程

1 基础概念 1.1 socket概念 Socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。Socket本质上是一个抽象层,它是一组用于网络通信的API,包括了一系列…

图片处理相关网站(图片分辨率、尺寸修改、AI扩图等)

分享一些免费的可进行图片的各种处理的网站,包括图片分辨率、尺寸修改、AI扩图等,持续增加中。。。 1.photokit.com 可进行图片分辨率、尺寸、压缩等修改。 免费在线图片编辑器 - 在线抠图、改图、修图、美图 - PhotoKit.comPhotoKit是一款免费的…

浅析PCIe 6.0功能更新与实现的挑战-2

确保TX重试缓冲区的准确性也非常重要,因为在接收到确认或否定信号之前,所有FLIT都需要存储在缓冲区中。由于一个FLIT可能包含多个TLP,或者一个大TLP可以被分割成多个FLIT,因此必须保证重传的FLIT不会跳过或额外添加原始FLIT中的TL…

【算法与数据结构】968、LeetCode监控二叉树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题的一共有两个难点,一个在于如何遍历二叉树(前中后遍历,选择什么…

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

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

C++面试宝典第12题:数组元素相除

题目 从控制台输入若干个整数作为数组,将数组中每一个元素除以第一个元素的结果,作为新的数组元素值。比如:可以先输入3,作为数组元素的个数;然后输入3个整数,作为数组元素的值。 解析 这道题本身并不复杂,但里面隐藏了不少“坑点”和“雷区”,主要考察应聘者全面思考问…

基于rockpi4b启动流程(2)

uboot启动kernel 基于上篇文章,将开发板烧录loder和system镜像,即可开机进console。 我们将系统停到uboot命令行,printenv看下环境变量 => printenv arch=arm baudrate=1500000 board=evb_rk3399 board_name=evb_rk3399 boot_a_script=load ${devtype} ${devnum}:${di…

4.32 构建onnx结构模型-Erf

前言 构建onnx方式通常有两种: 1、通过代码转换成onnx结构,比如pytorch —> onnx 2、通过onnx 自定义结点,图,生成onnx结构 本文主要是简单学习和使用两种不同onnx结构, 下面以 Erf 结点进行分析 方式 方法一&…

【Linux 内核源码分析】GPIO子系统软件框架

Linux内核的GPIO子系统是用于管理和控制通用输入输出(GPIO)引脚的软件框架。它提供了一套统一的接口和机制,使开发者能够方便地对GPIO进行配置、读写和中断处理。 主要组件: GPIO框架:提供了一套API和数据结构&#x…

Python爬虫---selenium基本使用(支持无界面浏览器PhantomJS和Chrome handless)

为什么使用selenium? 使用urllib.request.urlopen()模拟浏览器有时候获取不到数据,所以使用selenium (1) selenium是一个用于web应用程序测试的工具 (2) selenium 测试直接运行在浏览器中,就像真正的用户在操作一样 (3) 支持通过各种driver (FirfoxDri…

【Matlab】ELM极限学习机时序预测算法(附代码)

资源下载: https://download.csdn.net/download/vvoennvv/88681649 一,概述 ELM(Extreme Learning Machine)是一种单层前馈神经网络结构,与传统神经网络不同的是,ELM的隐层神经元权重以及偏置都是随机产生的…

系统架构设计师笔记

第1章计算机组成与体系结构 1.1.1计算机硬件的组成 (1)控制器。控制器是分析和执行指令的部件,也是统一指挥并控制计算机各部件协调工作的中心部件,所依据的是机器指令。控制器的组成包含如下。 ①程序计数器PC:存储下…

CopyTranslator11安装包下载及安装教程

CopyTranslator 10下载链接:https://docs.qq.com/doc/DUmJlS1NJb3hYZnJl 1.鼠标右击下载的压缩包选择【解压到copytranslator 11.0】文件夹 2.打开解压得到的文件夹,鼠标右击【copytranslator-setup-11.0.0.exe】,选择以管理员身份运行 3.点击…

【操作系统xv6】学习记录4 -CPU上下文:进程上下文、线程上下文、中断上下文

什么是cpu上下文 CPU 寄存器和程序计数器就是 CPU 上下文,因为它们都是 CPU 在运行任何任务前,必须的依赖环境。 什么是 CPU 上下文切换 先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后…