解决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如何替换某个文件中的字符串
Apr 25 Golang
基于Go Int转string几种方式性能测试
Apr 28 Golang
golang goroutine顺序输出方式
Apr 29 Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 Golang
go xorm框架的使用
May 22 Golang
go语言中http超时引发的事故解决
Jun 02 Golang
go select编译期的优化处理逻辑使用场景分析
Jun 28 Golang
Go语言基础切片的创建及初始化示例详解
Nov 17 Golang
golang操作rocketmq的示例代码
Apr 06 Golang
Golang入门之计时器
May 04 Golang
go goth封装第三方认证库示例详解
Aug 14 Golang
Go gorilla/sessions库安装使用
Aug 14 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 VS ASP
2006/10/09 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
详解PHP中curl_multi并发的实现
2020/06/08 PHP
不要小看注释掉的JS 引起的安全问题
2008/12/27 Javascript
jquery基础教程之数组使用详解
2014/03/10 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
jquery表单插件form使用方法详解
2017/01/20 Javascript
解决vue2.x中数据渲染以及vuex缓存的问题
2017/07/13 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
深入理解Vue 的钩子函数
2018/09/05 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
vue slot与传参实例代码讲解
2019/04/28 Javascript
js Array.slice的8种不同用法示例
2019/07/10 Javascript
vue-cli3+typescript新建一个项目的思路分析
2019/08/06 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
[02:39]DOTA2英雄基础教程 极限穿梭编织者
2013/12/05 DOTA
python mysqldb连接数据库
2009/03/16 Python
使用cx_freeze把python打包exe示例
2014/01/24 Python
Python导入txt数据到mysql的方法
2015/04/08 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
理解Python垃圾回收机制
2016/02/12 Python
解决Python requests 报错方法集锦
2017/03/19 Python
python连接数据库的方法
2017/10/19 Python
python实现图像拼接
2020/03/05 Python
Keras - GPU ID 和显存占用设定步骤
2020/06/22 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
Under Armour瑞典官方网站:美国高端运动科技品牌
2018/11/21 全球购物
Linux上比较文件的命令都有哪些
2012/02/24 面试题
煤矿机修工岗位职责
2014/02/07 职场文书
超市重阳节活动方案
2014/02/10 职场文书
幼儿园端午节活动方案
2014/08/25 职场文书
2016年大学生暑期社会实践活动总结
2016/04/06 职场文书
珍惜时间的诗歌赏析
2019/08/23 职场文书