首頁 > 後端開發 > Golang > 如何解決杜松子酒中的'標頭已寫入。想要用 400 覆蓋狀態代碼 200”

如何解決杜松子酒中的'標頭已寫入。想要用 400 覆蓋狀態代碼 200”

WBOY
發布: 2024-02-10 20:39:08
轉載
1033 人瀏覽過

如何解决杜松子酒中的“标头已写入。想要用 400 覆盖状态代码 200”

php小編子墨為您介紹解決杜松子酒中的「標頭已寫入。想要用 400 覆蓋狀態代碼 200」問題的方法。這個問題通常發生在使用PHP進行網頁開發時,可能會導致網頁無法正常載入。解決方法包括檢查程式碼中的重複輸出、清空緩衝區、檢查伺服器配置等。透過適當的措施,您可以輕鬆解決這個問題,確保您的網頁能夠正常運作。

問題內容

我正在嘗試使用 Gin 框架獨立於 HTTP 請求來計算報告,但如果尚未關閉,我也想將其返回到請求。以下程式碼片段有時可以正常工作,但有時會拋出錯誤「標頭已寫入。想要用 400 覆蓋狀態代碼 200」。我找不到解決方案。

// router.go
reportRoute.POST("/query", func(c *gin.Context) {
        reporter.ReportInChan <- c
    }) // Unpublish report by id
登入後複製
//reporter
package reporter

import (
    "fmt"
    "github.com/gin-gonic/gin"
)

var (
    ReportInChan = make(chan *gin.Context)
)

func Listener() {
    for {
        select {
        case req := <-ReportInChan:
            queryReports(req)
        }
    }
}

func queryReports(req *gin.Context) {
    type ReqQuery struct {
        QueryID    uint           `json:"query_id"`
        Parameters map[string]any `json:"parameters"`
    }
    type Req struct {
        ReportID uint       `json:"report_id"`
        Queries  []ReqQuery `json:"queries"`
    }

    var reqBody Req
    err := req.BindJSON(&reqBody)
    if err != nil {
        fmt.Println("hata var")
        if ctx := req.Request.Context(); ctx.Done() == nil {
            req.JSON(400, gin.H{"error": "Veriler Yanlış Gönderiliyor. Lütfen Bilgi İşlem Birimiyle İletişime Geçin ", "data": nil})
        }
        return
    }
}
登入後複製

解決方法

下面的處理程序會將上下文傳送到頻道,然後傳回。一旦處理程序返回,請求將被取消。此時,接收 Goroutine 可能根本沒有機會產生任何輸出,但有時可能會產生任何輸出。如果接收 Goroutine 在 Gin 框架寫入回應之後但在取消上下文之前開始產生輸出,您將收到上述錯誤。

reportRoute.POST("/query", func(c *gin.Context) {
        reporter.ReportInChan <- c
})
登入後複製

您真正需要做的是實現一個逾時方案,因此如果請求處理程序可以在該逾時之前回應,則將其寫入輸出並返回。否則,您讓請求處理程序運行,並找到另一種方法將結果傳回給呼叫者,可能是透過另一個 API 呼叫:

type reportRequest struct {
    ReportParams
    result chan ReportResult
}

reportRoute.POST("/query", func(c *gin.Context) {
        req:=reportRequest {
              ReportParams: {...},
              result: make(chan ReportResult),
        }
        reporter.ReportInChan <- req
        select {
           case time.After(100*time.Millisecond): 
               // Wait 100 msecs 
           case result<-req.result:
               // Write the result
        }
})
登入後複製

上面的程式碼將從請求上下文建立一個報告請求,建立一個返回通道,然後將其傳送到報告處理器。如果報表處理器在 100 毫秒內回應,則可以寫入結果。否則,結果應儲存在可以由另一個 API 檢索的其他位置。

報表處理器應如下所示:

func (r Reporter) reportProcessor() {
   for request:=range r.ReportInChan {
       result:=processReport(request)
       select {
          case request.result <- result:
              // Wrote the result
          default:
               // Cannot write the result, handler returned
             storeResult(result)
   }
}
登入後複製

以上是如何解決杜松子酒中的'標頭已寫入。想要用 400 覆蓋狀態代碼 200”的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板