欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go-zero讀取請(qǐng)求體出現(xiàn)EOF錯(cuò)誤的解決方法

 更新時(shí)間:2025年02月05日 08:32:54   作者:PandaMiner  
這篇文章主要為大家詳細(xì)介紹了go-zero讀取請(qǐng)求體出現(xiàn)EOF錯(cuò)誤時(shí)如何解決,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

最近自己在搭 go-zero 的腳手架,遇到一個(gè)問(wèn)題,原先的一個(gè) post 請(qǐng)求是執(zhí)行成功,當(dāng)我添加了一個(gè)過(guò)濾器之后執(zhí)行該請(qǐng)求就會(huì)報(bào)錯(cuò)請(qǐng)求體讀取 EOF 錯(cuò)誤,我感到有點(diǎn)奇怪,為什么過(guò)濾器中的邏輯會(huì)影響到后續(xù)的請(qǐng)求呢?在此記錄下這次的坑。

問(wèn)題分析

先上結(jié)論,這是由于 go 中 http.Request.Body 請(qǐng)求體是一個(gè)流,它只能被讀取一次,假如你在過(guò)濾器已經(jīng)進(jìn)行過(guò)流的讀取,那么在后續(xù)的請(qǐng)求中就讀取不到了。

示例的請(qǐng)求邏輯是這樣,當(dāng)請(qǐng)求到達(dá)后臺(tái)時(shí),先經(jīng)過(guò)過(guò)濾器檢查請(qǐng)求頭中是否攜帶 token,否則則請(qǐng)求失敗,成功則繼續(xù) post 請(qǐng)求邏輯,本次的 post 請(qǐng)求和過(guò)濾器只是做示例使用,邏輯很簡(jiǎn)單,過(guò)濾器中的邏輯就是去獲取請(qǐng)求 header 中 token 字段,如果這個(gè)字段為空,則請(qǐng)求失敗,代碼示例如下:

func tokenFilter(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
       type Request struct {
          Token string `header:"token"`
       }
       var req Request
       err := httpx.Parse(r, &req)
       if err != nil || req.Token == "" {
          resp, _ := utils.ToJsonString(models.ErrorResponseWithCode(http.StatusUnauthorized, "token required"))
          routers.HttpError(w, http.StatusUnauthorized, resp)
          return
       }
       next(w, r)
    }
}

按照官方文檔推薦,在過(guò)濾器我使用了 httpx.Parse(r, &req) 獲取請(qǐng)求體數(shù)據(jù),導(dǎo)致后續(xù) post 請(qǐng)求邏輯讀取請(qǐng)求體失敗,也就是說(shuō),這個(gè)方法中會(huì)消耗掉請(qǐng)求體流的數(shù)據(jù),查看源碼可以發(fā)現(xiàn),這個(gè)方法是會(huì)讀取請(qǐng)求中的 path,form,header,body 數(shù)據(jù),賦值到我們的 struct 中:

func Parse(r *http.Request, v any) error {
    kind := mapping.Deref(reflect.TypeOf(v)).Kind()
    if kind != reflect.Array && kind != reflect.Slice {
       if err := ParsePath(r, v); err != nil {
          return err
       }

       if err := ParseForm(r, v); err != nil {
          return err
       }

       if err := ParseHeaders(r, v); err != nil {
          return err
       }
    }

    if err := ParseJsonBody(r, v); err != nil {
       return err
    }

    if valid, ok := v.(validation.Validator); ok {
       return valid.Validate()
    } else if val := validator.Load(); val != nil {
       return val.(Validator).Validate(r, v)
    }

    return nil
}

繼續(xù)往下查看源碼可以發(fā)現(xiàn),其中的 ParseForm 方法和 ParseJsonBody 方法就會(huì)消耗掉請(qǐng)求體流的數(shù)據(jù),ParsePath 方法 ParseHeaders 方法則不會(huì),而在這個(gè)過(guò)濾器中,我們只需要獲取 header 的數(shù)據(jù),body 的數(shù)據(jù)需要由后續(xù)邏輯獲取,所以在這里需要修改過(guò)濾只獲取 header 數(shù)據(jù)的方法,如果需要的是 path 數(shù)據(jù)也是同樣的道理,修改后的過(guò)濾器:

func tokenFilter(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
       type Request struct {
          Token string `header:"token"`
       }
       var req Request
       err := httpx.ParseHeaders(r, &req)
       if err != nil || req.Token == "" {
          resp, _ := utils.ToJsonString(models.ErrorResponseWithCode(http.StatusUnauthorized, "token required"))
          routers.HttpError(w, http.StatusUnauthorized, resp)
          return
       }
       next(w, r)
    }
}

修改后后續(xù)節(jié)點(diǎn)即可正常獲取請(qǐng)求體數(shù)據(jù)。

完整示例代碼請(qǐng)參考:igolang

到此這篇關(guān)于go-zero讀取請(qǐng)求體出現(xiàn)EOF錯(cuò)誤的解決方法的文章就介紹到這了,更多相關(guān)解決go-zero讀取請(qǐng)求體出現(xiàn)EOF錯(cuò)誤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決goland中編輯tpl文件不高亮沒(méi)智能補(bǔ)全的問(wèn)題

    解決goland中編輯tpl文件不高亮沒(méi)智能補(bǔ)全的問(wèn)題

    這篇文章主要介紹了解決goland中編輯tpl文件不高亮沒(méi)智能補(bǔ)全的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • golang的HTTP基本認(rèn)證機(jī)制實(shí)例詳解

    golang的HTTP基本認(rèn)證機(jī)制實(shí)例詳解

    這篇文章主要介紹了golang的HTTP基本認(rèn)證機(jī)制,結(jié)合實(shí)例形式較為詳細(xì)的分析了HTTP請(qǐng)求響應(yīng)的過(guò)程及認(rèn)證機(jī)制實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-07-07
  • 深入理解Golang channel的應(yīng)用

    深入理解Golang channel的應(yīng)用

    channel是用于 goroutine 之間的同步、通信的數(shù)據(jù)結(jié)構(gòu)。它為程序員提供了更高一層次的抽象,封裝了更多的功能,這樣并發(fā)編程變得更加容易和安全。本文通過(guò)示例為大家詳細(xì)介紹了channel的應(yīng)用,需要的可以參考一下
    2022-10-10
  • Golang 關(guān)于Gin框架請(qǐng)求參數(shù)的獲取方法

    Golang 關(guān)于Gin框架請(qǐng)求參數(shù)的獲取方法

    Gin是Go語(yǔ)言的Web框架,提供路由和中間件支持,本文介紹如何使用Gin獲取HTTP請(qǐng)求參數(shù),包括URLPath參數(shù)、URLQuery參數(shù)、HTTPBody參數(shù)和Header參數(shù),詳解直接獲取和綁定到結(jié)構(gòu)體兩種方法,幫助開(kāi)發(fā)者高效處理Web請(qǐng)求
    2024-10-10
  • Go項(xiàng)目實(shí)現(xiàn)優(yōu)雅關(guān)機(jī)與平滑重啟功能

    Go項(xiàng)目實(shí)現(xiàn)優(yōu)雅關(guān)機(jī)與平滑重啟功能

    無(wú)論是優(yōu)雅關(guān)機(jī)還是優(yōu)雅重啟歸根結(jié)底都是通過(guò)監(jiān)聽(tīng)特定系統(tǒng)信號(hào),然后執(zhí)行一定的邏輯處理保障當(dāng)前系統(tǒng)正在處理的請(qǐng)求被正常處理后再關(guān)閉當(dāng)前進(jìn)程,這篇文章主要介紹了Go實(shí)現(xiàn)優(yōu)雅關(guān)機(jī)與平滑重啟 ,需要的朋友可以參考下
    2022-10-10
  • Golang調(diào)用FFmpeg轉(zhuǎn)換視頻流的實(shí)現(xiàn)

    Golang調(diào)用FFmpeg轉(zhuǎn)換視頻流的實(shí)現(xiàn)

    本文主要介紹了Golang調(diào)用FFmpeg轉(zhuǎn)換視頻流,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 在Go語(yǔ)言單元測(cè)試中解決HTTP網(wǎng)絡(luò)依賴問(wèn)題

    在Go語(yǔ)言單元測(cè)試中解決HTTP網(wǎng)絡(luò)依賴問(wèn)題

    在 Go 語(yǔ)言中,我們需要找到一種可靠的方法來(lái)測(cè)試 HTTP 請(qǐng)求和響應(yīng),本文將探討在 Go 中進(jìn)行 HTTP 應(yīng)用測(cè)試時(shí),如何解決應(yīng)用程序的依賴問(wèn)題,以確保我們能夠編寫(xiě)出可靠的測(cè)試用例,需要的朋友可以參考下
    2023-07-07
  • Golang的第一個(gè)程序-Hello?World

    Golang的第一個(gè)程序-Hello?World

    這篇文章主要介紹了第一個(gè)Go程序-Hello?World,在編寫(xiě)第一個(gè)go程序之前,我們要將系統(tǒng)的環(huán)境變量配好,下面來(lái)看具體的編一過(guò)程吧,需要的小伙伴可以參考一下
    2022-01-01
  • Go 通過(guò)結(jié)構(gòu)struct實(shí)現(xiàn)接口interface的問(wèn)題

    Go 通過(guò)結(jié)構(gòu)struct實(shí)現(xiàn)接口interface的問(wèn)題

    這篇文章主要介紹了Go 通過(guò)結(jié)構(gòu)struct實(shí)現(xiàn)接口interface的問(wèn)題,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • 詳解Golang中Channel的原理和使用技巧

    詳解Golang中Channel的原理和使用技巧

    Channel管道提供了一種機(jī)制,它在兩個(gè)并發(fā)執(zhí)行的協(xié)程之間進(jìn)行同步,并通過(guò)傳遞與該管道元素類型相符的值來(lái)進(jìn)行通信。本文主要介紹了Channel的原理和使用技巧,需要的可以參考一下
    2022-11-11

最新評(píng)論