解决Golang中ResponseWriter的一个坑


Posted in Golang onApril 27, 2021

在使用Context.ResponseWriter中的Set/WriteHeader/Write这三个方法时,使用顺序必须如下所示,否则会出现某一设置不生效的情况。

ctx.ResponseWriter.Header().Set("Content-type", "application/text")
 ctx.ResponseWriter.WriteHeader(403)
 ctx.ResponseWriter.Write([]byte(resp))

如1:

ctx.ResponseWriter.Header().Set("Content-type", "application/text")
 ctx.ResponseWriter.Write([]byte(resp))
 ctx.ResponseWriter.WriteHeader(403)

会导致返回码一直是200

补充:Go里w http.ResponseWriter,调用w.Write()方法报错

Go里w http.ResponseWriter写入报错

http: request method or response status code does not allow

1. 下面是报错截图

解决Golang中ResponseWriter的一个坑

2. 点进去Write方法

它首先是一个接口;

由于它是在HTTP web服务器的应用场景,所以它具体的实现方法在net/http/server.go里:

func (w *response) Write(data []byte) (n int, err error) {
 return w.write(len(data), data, "")
}

再点进去,函数里你会发现有一个关键的判断

// 其中ErrBodyNotAllowed的
// 代码内容
// ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
if !w.bodyAllowed() {
 return 0, ErrBodyNotAllowed
}

点进去,发现它在没有设置Header时会panic,当然这跟我们当前要讨论的问题关系不大,关键在bodyAllowedForStatus()方法

func (w *response) bodyAllowed() bool {
 if !w.wroteHeader {
  panic("")
 }
 return bodyAllowedForStatus(w.status)
}

再点,终于看到了,当设置状态码为【100,199】、204、304就会报这个错,而我刚好设置的状态码就是204,我把它改成200重新试下,问题解决。

func bodyAllowedForStatus(status int) bool {
 switch {
 case status >= 100 && status <= 199:
  return false
 case status == 204:
  return false
 case status == 304:
  return false
 }
 return true
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
golang在GRPC中设置client的超时时间
Apr 27 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
go设置多个GOPATH的方式
May 05 Golang
Golang全局变量加锁的问题解决
May 08 Golang
Go timer如何调度
Jun 09 Golang
Golang的继承模拟实例
Jun 30 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
Golang 1.18 多模块Multi-Module工作区模式的新特性
Apr 11 Golang
Golang数据类型和相互转换
Apr 12 Golang
Golang 链表的学习和使用
Apr 19 Golang
Go Grpc Gateway兼容HTTP协议文档自动生成网关
Jun 16 Golang
golang在GRPC中设置client的超时时间
golang http使用踩过的坑与填坑指南
Apr 27 #Golang
Golang 实现超大文件读取的两种方法
Apr 27 #Golang
golang中的空slice案例
Apr 27 #Golang
Go语言切片前或中间插入项与内置copy()函数详解
golang中切片copy复制和等号复制的区别介绍
Apr 27 #Golang
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 #Golang
You might like
php 转换字符串编码 iconv与mb_convert_encoding的区别说明
2011/11/10 PHP
php获取四位字母和数字的随机数的实现方法
2015/01/09 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
CentOS下PHP7的编译安装及MySQL的支持和一些常见问题的解决办法
2015/12/17 PHP
PHP图形计数器程序显示网站用户浏览量
2016/07/20 PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
2016/11/05 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
JQuery实现鼠标滑过显示导航下拉列表
2013/09/12 Javascript
js 点击页面其他地方关闭弹出层(示例代码)
2013/12/24 Javascript
浅析jquery某一元素重复绑定的问题
2014/01/03 Javascript
jQuery插件开发精品教程让你的jQuery提升一个台阶
2016/01/27 Javascript
jquery自适应布局的简单实例
2016/05/28 Javascript
vue mounted组件的使用
2018/06/18 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
详解javascript 变量提升(Hoisting)
2019/03/12 Javascript
vite2.0+vue3移动端项目实战详解
2021/03/03 Vue.js
[01:19:11]Ti4 循环赛第二日 NaVi.us vs iG
2014/07/11 DOTA
[05:20]2018DOTA2亚洲邀请赛主赛事第三日战况回顾 LGD率先挺进胜者组决赛
2018/04/06 DOTA
python计算圆周率pi的方法
2015/07/11 Python
浅谈django的render函数的参数问题
2018/10/16 Python
pandas 把数据写入txt文件每行固定写入一定数量的值方法
2018/12/28 Python
pyqt5 实现在别的窗口弹出进度条
2019/06/18 Python
解决pyqt5中QToolButton无法使用的问题
2019/06/21 Python
python pytest进阶之conftest.py详解
2019/06/27 Python
pytorch中的embedding词向量的使用方法
2019/08/18 Python
快速解释如何使用pandas的inplace参数的使用
2020/07/23 Python
在python中对于bool布尔值的取反操作
2020/12/11 Python
2014公司党员自我评价范文
2014/09/11 职场文书
党员教师个人对照检查材料范文
2014/09/25 职场文书
2014年党风廉政工作总结
2014/12/03 职场文书
大学生个人总结范文
2015/02/15 职场文书
导师工作推荐信
2015/03/27 职场文书
基于Redis过期事件实现订单超时取消
2021/05/08 Redis