Heim  >  Artikel  >  Backend-Entwicklung  >  So lösen Sie „Header wurde geschrieben. Sie möchten den Statuscode 200 mit 400 überschreiben“ in Gin

So lösen Sie „Header wurde geschrieben. Sie möchten den Statuscode 200 mit 400 überschreiben“ in Gin

WBOY
WBOYnach vorne
2024-02-10 20:39:08986Durchsuche

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

php-Editor Zimo stellt Ihnen die Methode vor, um das Problem „Header wurde geschrieben. Sie möchten den Statuscode 200 mit 400 überschreiben“ in Gin zu lösen. Dieses Problem tritt normalerweise auf, wenn PHP für die Webentwicklung verwendet wird, und kann dazu führen, dass die Webseite nicht richtig geladen wird. Zu den Lösungen gehören die Überprüfung Ihres Codes auf doppelte Ausgaben, das Löschen von Puffern, das Überprüfen der Serverkonfiguration usw. Wenn Sie die entsprechenden Schritte unternehmen, können Sie dieses Problem leicht beheben und sicherstellen, dass Ihre Seiten ordnungsgemäß funktionieren.

Inhalt der Frage

Ich versuche mit dem Gin-Framework einen Bericht unabhängig von der HTTP-Anfrage zu berechnen, möchte ihn aber auch an die Anfrage zurückgeben, wenn diese noch nicht geschlossen wurde. Das folgende Code-Snippet funktioniert manchmal einwandfrei, gibt aber manchmal den Fehler „Header bereits geschrieben. Statuscode 200 sollte mit 400 überschrieben werden“ aus. Ich kann keine Lösung finden.

// 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
    }
}

Workaround

Der Handler unten sendet den Kontext an den Kanal und kehrt dann zurück. Sobald der Handler zurückkehrt, wird die Anfrage abgebrochen. Zu diesem Zeitpunkt hat die empfangende Goroutine möglicherweise keine Chance, überhaupt eine Ausgabe zu erzeugen, aber manchmal kann sie überhaupt eine Ausgabe erzeugen. Wenn die empfangende Goroutine mit der Ausgabe beginnt, nachdem das Gin-Framework die Antwort geschrieben hat, aber bevor der Kontext abgebrochen wird, erhalten Sie die obige Fehlermeldung.

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

Was Sie wirklich tun müssen, ist ein Timeout-Schema zu implementieren. Wenn der Anforderungshandler also vor diesem Timeout antworten kann, schreibt er es in die Ausgabe und gibt es zurück. Andernfalls lassen Sie den Request-Handler laufen und finden eine andere Möglichkeit, das Ergebnis an den Aufrufer zurückzugeben, wahrscheinlich über einen anderen API-Aufruf:

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
        }
})

Der obige Code erstellt eine Berichtsanforderung aus dem Anforderungskontext, erstellt einen Rückkanal und sendet ihn dann an den Berichtsprozessor. Wenn der Berichtsprozessor innerhalb von 100 Millisekunden antwortet, können die Ergebnisse geschrieben werden. Andernfalls sollten die Ergebnisse an einem anderen Ort gespeichert werden, wo sie von einer anderen API abgerufen werden können.

Der Berichtsprozessor sollte so aussehen:

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)
   }
}

Das obige ist der detaillierte Inhalt vonSo lösen Sie „Header wurde geschrieben. Sie möchten den Statuscode 200 mit 400 überschreiben“ in Gin. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen