Maison  >  Article  >  développement back-end  >  Comment résoudre "L'en-tête a été écrit. Vous souhaitez écraser le code d'état 200 par 400" dans Gin

Comment résoudre "L'en-tête a été écrit. Vous souhaitez écraser le code d'état 200 par 400" dans Gin

WBOY
WBOYavant
2024-02-10 20:39:08986parcourir

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

L'éditeur PHP Zimo vous présente la méthode pour résoudre le problème "L'en-tête a été écrit. Vous souhaitez écraser le code d'état 200 par 400" dans Gin. Ce problème se produit généralement lors de l'utilisation de PHP pour le développement Web et peut empêcher le chargement correct de la page Web. Les solutions incluent la vérification des sorties en double dans votre code, la suppression des tampons, la vérification de la configuration du serveur, etc. En prenant les mesures appropriées, vous pouvez facilement résoudre ce problème et vous assurer que vos pages fonctionnent correctement.

Contenu de la question

J'essaie d'utiliser le framework Gin pour calculer un rapport indépendamment de la requête HTTP, mais je souhaite également le renvoyer à la requête si elle n'a pas encore été fermée. L'extrait de code suivant fonctionne parfois correctement mais renvoie parfois l'erreur "En-tête déjà écrit. Je voulais écraser le code d'état 200 par 400". Je ne trouve pas de solution.

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

Solution de contournement

Le gestionnaire ci-dessous enverra le contexte au canal puis reviendra. Une fois le gestionnaire revenu, la demande sera annulée. À ce stade, le goroutine récepteur n'a peut-être aucune chance de produire un résultat, mais il peut parfois produire n'importe quel résultat. Si le Goroutine de réception commence à produire une sortie après que le framework Gin ait écrit la réponse mais avant que le contexte ne soit annulé, vous recevrez l'erreur ci-dessus.

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

Ce que vous devez vraiment faire est d'implémenter un schéma de délai d'attente, donc si le gestionnaire de requêtes peut répondre avant ce délai, il l'écrit dans la sortie et le renvoie. Sinon, vous laissez le gestionnaire de requêtes s'exécuter et trouvez un autre moyen de renvoyer le résultat à l'appelant, probablement via un autre appel 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
        }
})

Le code ci-dessus créera une demande de rapport à partir du contexte de la demande, créera un canal de retour, puis l'enverra au processeur de rapport. Si le processeur de rapports répond dans les 100 millisecondes, les résultats peuvent être écrits. Sinon, les résultats doivent être stockés ailleurs où ils peuvent être récupérés par une autre API.

Le processeur de rapports devrait ressembler à ceci :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer