mehrere Antwort.WriteHeader Anrufe in ganz einfaches Beispiel?
Habe ich die meisten basic-net/http-Programm, das ich verwende, um zu lernen, den namespace im Gehen:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
go HandleIndex(w, r)
})
fmt.Println("Starting Server...")
log.Fatal(http.ListenAndServe(":5678", nil))
}
func HandleIndex(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("Hello, World!"))
}
Wenn ich das Programm starte und eine Verbindung zu localhost:5678
in Chrom, bekomme ich diese in der Konsole:
Starting Server...
/
2015/01/15 13:41:29 http: multiple response.WriteHeader calls
/favicon.ico
2015/01/15 13:41:29 http: multiple response.WriteHeader calls
Aber ich sehe nicht, wie das möglich ist. Ich drucken Sie das URL, das starten einer neuen goroutine, schreib die header einmal, und geben Sie einen statischen Körper von Hello, World!
wie Es scheint, eines von zwei Dingen geschieht. Entweder etwas, was hinter die Szenen zu schreiben ist eine andere Kopf-oder irgendwie HandleIndex
genannt wird, zweimal für die gleiche Anfrage. Was kann ich tun, um zu stoppen schreiben mehrere Header?
EDIT: Es scheint etwas zu tun mit der go HandleIndex(w, r)
Linie, weil wenn ich Sie entfernen go
und es muss nur eine Funktion aufrufen, statt eine goroutine, ich bekomme keine Probleme und der browser erhält seine Daten. Mit ihm wird eine goroutine, bekomme ich mehrere WriteHeader Fehler und der browser nicht anzeigen "Hello World." Warum ist diese eine goroutine zu brechen?
InformationsquelleAutor der Frage Corey Ogburn | 2015-01-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werfen Sie einen Blick auf die anonyme Funktion, die Sie registrieren Sie sich als handler für eingehende Anfragen:
Druckt es die URL (die standard-Ausgabe) ruft dann
HandleIndex()
in einer neuen goroutine und setzt die Ausführung Fort.Wenn Sie eine handler-Funktion, wenn Sie nicht die Antwort-status, bevor der erste Aufruf
Write
Gehen automatisch die response status 200 HTTP (OK). Wenn der handler-Funktion nicht alles schreiben, auf die Antwort (und nicht den Antwort-status und wird normal ausgeführt), wird auch behandelt, wie eine erfolgreiche Abwicklung der Anfrage und der Antwort-status 200 zurück gesendet. Ihre anonymen Funktion nicht festgelegt, es muss nicht einmal alles schreiben, was zu der Reaktion. So Gehen Sie wird genau das tun: legen Sie den response status 200 HTTP-OK.Beachten Sie, dass der Umgang mit jeder Anfrage wird in seiner eigenen goroutine.
So, wenn Sie anrufen
HandleIndex
in einer neuen goroutine, Ihre ursprüngliche anonyme Funktion weiter: Sie wird zu Ende gehen und so die response-header gesetzt wird - währenddessen (gleichzeitig) Ihre begonnenen neuen goroutine wird auch die response-header - daher der"multiple response.WriteHeader calls"
Fehler.Wenn Sie entfernen die
"go"
IhreHandleIndex
Funktion setzt die response-header in der gleichen goroutine, bevor Sie Ihre handler-Funktion gibt, und die "net/http" wird das kennen und nicht versuchen, die Antwort-header wieder, also der Fehler, den Sie erlebt, wird nicht passieren.InformationsquelleAutor der Antwort icza
Da moderne Browser schicken ein extra Antrag für /favicon.ico die auch behandelt in Ihrem /request-handler.
Wenn Sie ping-Sie Ihre server mit curl zum Beispiel, sehen Sie nur eine Anfrage gesendet:
Werden Sie sicher, dass Sie hinzufügen können, ein Endpunkt in Ihrer http.HandleFunc
InformationsquelleAutor der Antwort abdel
Du bereits eine richtige Antwort, welche Adressen Ihr problem, ich werde Ihnen einige Informationen über den Allgemeinen Fall (solche Fehler erscheint Häufig).
Aus der Dokumentationsehen Sie, dass
WriteHeader
sendet ein http-status-code und Sie können nicht senden mehr als 1-status-code. Wenn SieWrite
alles dies ist gleichbedeutend mit Versand 200 status-code und dann schreiben, Dinge.Also die Nachricht, die Sie sehen erscheint, wenn Sie entweder vom Benutzer
w.WriteHeader
mehr als einmal explizit oder verwendetw.Write
vorw.WriteHeader
.InformationsquelleAutor der Antwort Salvador Dali
die Ursache ist, dass Sie genannt WriteHeader mehr als einmal. aus den source-codes
so, wenn Sie einmal geschrieben, die variable wroteHeader wäre wahr, dann Sie schrieb header wieder, würde es nicht wirksam zu sein, und gab eine Warnung "http: mehrere respnse.WriteHeader fordert".
tatsächlich die Funktion Schreiben, fordert auch WriteHeader, so setzen die Funktion WriteHeader nach der Funktion Schreiben wird auch bewirkt, dass Fehler, die später WriteHeader nicht funktioniert.
von Ihrem Fall, gehen Sie handleindex läuft in einem anderen thread und das original bereits gibt, wenn Sie nichts tun, wird es rufen WriteHeader zum 200. beim laufen handleindex, ruft es eine andere WriteHeader, damals wroteHeader wahr ist, dann wird die Nachricht "http: multiple response.WriteHeader" nennt, ist Ausgang.
InformationsquelleAutor der Antwort user7402259
Aus der Dokumentation:
Was ist passiert in deinem Fall ist, dass Sie starten
go HandleIndex
von der hf.Der erste handler beendet ist. Die standard-WriteHeader schreibt in den ResponseWriter. Dann die go-routine HandleIndex gestartet wird und auch versucht zu schreiben, ein header und schreiben.
Entfernen Sie einfach die
go
aus HandleIndex und es wird funktionieren.InformationsquelleAutor der Antwort fabrizioM
Ja, verwenden Sie
HandleIndex(w, r)
stattgo HandleIndex(w, r)
wird das Problem beheben, ich denke, Sie haben das schon herausgefunden.Der Grund ist einfach, wenn die Behandlung mehrerer Anfragen zur gleichen Zeit, der http-server startet mehrere goroutines und Ihre handler-Funktion aufgerufen wird, werden separat in jedem der goroutines, ohne zu blockieren andere.
Sie nicht brauchen, um Ihr eigenes goroutine in der Prozedur, es sei denn, Sie praktisch brauchen es, aber das wäre ein anderes Thema.
InformationsquelleAutor der Antwort Andy Xu