Geonode logo
Geonode Team

Geonode Team

Aktualisiert: 7. Oktober 2026

Veröffentlicht: 02.09.2026

So zeigen Sie Antwort-Header mit curl an

curl blendet Antwort-Header standardmäßig aus. Es gibt vier Optionen, um sie anzuzeigen, und diese unterscheiden sich in Punkten, die wichtiger sind, als in der Dokumentation angedeutet wird. Eine davon sendet eine andere Anfrage als die, die Sie zu debuggen versuchen – eine hervorragende Möglichkeit, eine Stunde damit zu verbringen, einer Diskrepanz hinterherzujagen, die gar nicht existiert. Dieser Leitfaden behandelt alle vier Optionen sowie die JSON-Ausgabe, die den meisten Nutzern unbekannt ist, und wie sich das Bild bei Verwendung eines Proxys verändert.

Warum uns das wichtig ist: Wir sind Geonode und verkaufen Proxys, und Antwort-Header sind der schnellste Weg, die Frage zu beantworten, die uns Kunden am häufigsten stellen – Ist das ein Proxy-Problem oder nicht? Eine Sperrseite, eine Ratenbegrenzung und ein echter Fehler sehen im Browser identisch aus, in den Headern jedoch völlig unterschiedlich. Ein 429 mit dem Header „Retry-After“ bedeutet, dass Sie zu schnell sind, und kein Proxy kann das beheben. Ein 403 mit einem „security-vendor“-Header bedeutet, dass das Ziel Sie identifiziert hat. Ein „407“ bedeutet, dass der Proxy Anmeldedaten verlangt. Das Lesen der Header vor dem Vornehmen von Änderungen erspart viel Rätselraten, und „curl“ verfügt über ein Flag für diesen speziellen Fall – „%{proxy_used}“, das in Version 8.7.0 hinzugefügt wurde und den Wert 1 zurückgibt, wenn die Übertragung über einen Proxy lief. Dies ist nützlich, wenn Sie sich nicht sicher sind, ob Ihre Konfiguration wirksam geworden ist.

Die vier Optionen im Überblick

OptionZeigt anSendetAm besten geeignet für
-iAntwort-Header + HauptteilIhre eigentliche AnfrageTägliche Überprüfung
-INur Antwort-HeaderEine HEAD-AnfrageSchnellüberprüfungen, mit einer Einschränkung
-D fileAntwort-Header in eine DateiIhre eigentliche AnfrageSkripterstellung, Trennung von Datenströmen
-vAnfrage- und Antwort-HeaderIhre eigentliche AnfrageDebugging Ihrer gesendeten Daten

Die entscheidende Zeile ist die zweite, und sie ist die Quelle der meisten Verwirrung in diesem Bereich. Bei allem anderen kommt es darauf an, wohin die Ausgabe geleitet wird.

-i

: Header zusammen mit dem Hauptteil Die gängige Option. Im Curl-Handbuch wird sie als „-i, --show-headers “ beschrieben: „Zeigt die Antwort-Header in der Ausgabe an … Mit dieser Option werden die Antwort-Header im selben Stream/in derselben Ausgabe wie die Daten gespeichert.“

curl -i https://example.com
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 1256
cache-control: max-age=604800
date: Wed, 02 Sep 2026 10:14:22 GMT

<!doctype html>...

Header, eine Leerzeile, dann der Body – dieselbe Struktur wie beim Wire-Format.

Ein Hinweis zur Namensgebung, der Lesern älterer Unterlagen auffallen dürfte: Die Langform lautet nun „--show-headers “. Früher hieß es „--include “, und beide funktionieren, aber die aktuelle Dokumentation verwendet den neueren Namen.

Zwei Details, die man wissen sollte: Bei der Ausgabe auf einem Terminal kann curl Header-Namen fett formatieren und URLs vom Typ Location: markieren, was im interaktiven Betrieb hilfreich, in einer Pipeline jedoch unerwünscht ist – --no-styled-output deaktiviert diese Funktion. Und da Header und Hauptteil denselben Stream nutzen, schreibt -i mit -o file beides in die Datei, was so gut wie nie gewünscht ist. Verwenden Sie in diesem Fall -D .

-I: Nur Header – und warum dies irreführend sein kann

-I wird wie folgt dokumentiert: „Ruft nur die Header ab. HTTP-Server verfügen über den Befehl HEAD, den diese Methode verwendet, um ausschließlich die Header eines Dokuments abzurufen.“

Lesen Sie das bitte sorgfältig durch. Es ruft nicht die Antwort ab und verwirft dann den Hauptteil. Es wird eine andere HTTP-Methode gesendet.

curl -I https://example.com

Das ist eine HEAD-Anfrage, und die Konsequenzen sind real:

Manche Server behandeln HEAD unterschiedlich. Ein HEAD kann andere Header oder einen anderen Statuscode zurückgeben oder mit einem 405 Method Not Allowed vollständig abgelehnt werden – während die entsprechende GET-Anfrage einwandfrei funktioniert.

Einige Frameworks berechnen den Body für HEAD nicht, sodass Content-Length, ETag und Content-Type möglicherweise fehlen oder falsch sind.

CDNs und Caches behandeln HEAD häufig als eigenständigen Cache-Schlüssel, sodass Cache-Header von denen abweichen können, die bei einer echten Anfrage angezeigt würden.

Anti-Bot-Systeme reagieren möglicherweise anders. Ein HEAD von einem ungewöhnlichen Client ist an sich schon ein Signal, und die Challenge, die Sie erhalten, ist möglicherweise nicht dieselbe, die ein GET erzeugen würde.

Daher eignet sich -I hervorragend für schnelle Überprüfungen – ist diese URL aktiv, wohin leitet sie weiter, wie groß ist die Datei? – ist jedoch unzuverlässig, um zu ermitteln, warum sich ein GET seltsam verhält. Wenn Sie eine echte Anfrage analysieren, verwenden Sie die richtige Methode:

curl -sS -o /dev/null -D - https://example.com

Das führt einen normalen GET durch, leitet den Body an /dev/null weiter und gibt die Header an die Standardausgabe aus. Es liefert Ihnen das, was -I scheinbar liefert, ohne die Anfrage zu verändern.

Wenn Sie speziell Header aus einem POST benötigen, gilt dasselbe Muster:

curl -sS -o /dev/null -D - -X POST -H "Content-Type: application/json" \
     -d '{"a":1}' https://api.example.com/items

-D und -v: Streams trennen und Anfragen anzeigen

-D schreibt Header in ein separates Ziel. Im Handbuch heißt es: „Schreibt die empfangenen Protokoll-Header in die angegebene Datei … Geben Sie ‚-‘ als Dateinamen an (ein einzelnes Minuszeichen), um die Ausgabe über stdout zu erfolgen.“ Es wird außerdem darauf hingewiesen, dass die Option „eine leere Datei erstellt“, wenn keine Header empfangen werden – was an sich bereits eine Diagnoseinformation ist.

curl -D headers.txt -o body.html https://example.com

Eine saubere Trennung, genau das, was man in Skripten haben möchte. -D - sendet Header an stdout, während der Body dorthin geleitet wird, wohin -o verweist, und diese Kombination bildet die Grundlage für das oben beschriebene Muster.

-v zeigt ebenfalls die Anfrage an, was häufig genau die Hälfte ist, die man tatsächlich benötigt. Das Handbuch erklärt die Präfixe genau:

Ausführliche Ausgabezeilen sind mit Buchstaben vorangestellt: > von curl gesendeter Header, < von curl empfangener Header, } von curl gesendete Daten, { von curl empfangene Daten, * zusätzliche Informationen von curl.

curl -v https://example.com 2>&1 | grep '^>'

Damit erhalten Sie genau das, was curl übertragen hat – was oft nicht Ihrer Konfiguration entspricht, da Bibliotheken, Standardeinstellungen und „.curlrc“-Dateien Header hinzufügen und überschreiben. Viele Probleme der Art „Der Server ignoriert meinen Header“ lassen sich hier lösen.

Beachten Sie, dass die ausführliche Ausgabe an stderr gesendet wird, weshalb vor der Weiterleitung der Befehl „2>&1“ erforderlich ist. Das ist beabsichtigt: So bleibt der Hauptteil der Ausgabe auf stdout übersichtlich.

Das Handbuch weist außerdem darauf hin, dass seit curl 8.10 die wiederholte Verwendung von -v die Trace-Stufe erhöht. Für wirklich tiefgreifende Analysen liefert --trace-ascii „einen vollständigen Trace-Dump aller ein- und ausgehenden Daten, einschließlich beschreibender Informationen“, wobei die Hexadezimalwerte weggelassen werden, damit die Ausgabe lesbar bleibt.

Eine Warnung aus dem Handbuch ist es wert, wiederholt zu werden: Trace- und Verbose-Ausgaben „können sensible Daten enthalten, darunter Benutzernamen, Anmeldedaten oder vertrauliche Inhalte. Seien Sie sich dessen bewusst und gehen Sie vorsichtig vor, wenn Sie Trace-Protokolle an andere weitergeben.“ In einer URL übergebene Proxy-Anmeldedaten erscheinen in der Verbose-Ausgabe. Schwärzen Sie diese, bevor Sie sie in einen Issue-Tracker einfügen.

Maschinenlesbare Header mit „%{header_json}

“ – die Option, die die meisten noch nie gesehen haben, die in curl 7.83.0 hinzugefügt wurde und die richtige Lösung ist, wenn man gerade dabei war, einen regulären Ausdruck für Header-Text zu schreiben.

Im Handbuch wird sie wie folgt beschrieben: „Ein JSON-Objekt mit allen HTTP-Antwort-Headern der letzten Übertragung. Die Werte werden als Arrays bereitgestellt, da es bei mehreren Headern mehrere Werte geben kann.“ Header-Namen werden „in Kleinbuchstaben und in der Reihenfolge ihres Auftretens im Datenstrom“ übergeben, wobei Duplikate „beim ersten Vorkommen dieses Headers gruppiert werden und jeder Wert im JSON-Array dargestellt wird“.

curl -s -o /dev/null -w '%{header_json}' https://example.com | jq
{
  "content-type": ["text/html; charset=UTF-8"],
  "cache-control": ["max-age=604800"],
  "set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}

Damit werden gleich drei Probleme auf einmal behoben. Namen werden in Kleinbuchstaben normalisiert, sodass kein groß-/kleinschreibungsunabhängiger Abgleich erforderlich ist. Wiederholte Header wie Set-Cookie werden als Arrays ausgegeben, anstatt stillschweigend zusammengefasst zu werden. Und die Ausgabe lässt sich ohne das Schreiben eines Parsers auswerten.

Das Extrahieren eines einzelnen Headers wird zum Kinderspiel:

curl -s -o /dev/null -w '%{header_json}' "$URL" | jq -r '.["retry-after"][0] // "none"'

Weitere „-w “-Variablen, die sich gut damit kombinieren lassen:

curl -s -o /dev/null -w 'status=%{response_code} redirects=%{num_redirects} proxy=%{proxy_used} ip=%{remote_ip}\n' "$URL"

„

response_code “ ist der Status der letzten Übertragung, „num_redirects “ zählt die durchgeführten Weiterleitungen, „redirect_url “ zeigt an, wohin eine Weiterleitung geführt hätte, wenn du „-L “ nicht verwendet hättest, „remote_ip “ ist die Adresse, mit der tatsächlich eine Verbindung hergestellt wurde, und „proxy_used “ gibt 1 zurück, wenn ein Proxy beteiligt war. Letzteres ist besonders nützlich, wenn ein „NO_PROXY “-Muster deinen Host möglicherweise stillschweigend ausgeschlossen hat.

Verfolgung von Weiterleitungs-Ketten

Ohne „-L

“ bricht curl bei der ersten Weiterleitung ab und Sie sehen nur diese Antwort. Mit „-L

“ zeigt curl die Header jeder Antwort in der Kette an:

curl -sSL -o /dev/null -D - https://example.com
HTTP/2 301
location: https://www.example.com/

HTTP/2 200
content-type: text/html

Jeder Block entspricht einem Schritt. So können Sie feststellen, dass eine URL dreimal umgeleitet wird, dass bei einem Schritt auf reines HTTP umgeschaltet wird oder dass bei einer Umleitung ein Cookie verloren geht.

Zwei Muster, die es sich zu merken lohnt:

curl -sSL -o /dev/null -w '%{num_redirects} hops -> %{url_effective}\n' "$URL"

Die Anzahl und das endgültige Ziel in einer Zeile. Und wenn Sie sehen möchten, wohin eine Weiterleitung führt, ohne ihr zu folgen:

curl -s -o /dev/null -w '%{redirect_url}\n' "$URL"

Weiterleitungsketten sollten häufiger überprüft werden, als dies üblicherweise der Fall ist. Jeder Sprung entspricht einem Hin- und Rückweg; eine Kette aus vier Sprüngen verursacht echte Latenz, und ein unerwarteter Sprung über einen anderen Host ist häufig die Ursache für ein Cookie- oder CORS-Problem.

Header über einen Proxy

Zwei Ergänzungen zum Gesamtbild, die beide auf den ersten Blick Verwirrung stiften.

** „CONNECT “-Antworten erscheinen in der ausführlichen Ausgabe.** Bei HTTPS über einen HTTP-Proxy sendet curl zunächst einen „CONNECT “, um einen Tunnel aufzubauen, und dieser Austausch hat eigene Header:

curl -v -x http://proxy.example.com:8080 https://example.com

Sie sehen den „CONNECT “, einen „HTTP/1.1 200 Connection established “ vom Proxy und erst danach die eigentliche Anfrage. Dieser erste Block stammt vom Proxy, nicht vom Ziel. Diese beiden zu verwechseln, ist ein häufiger Anfängerfehler. Mit ``--suppress-connect-headers werden sie aus der Ausgabe entfernt, wenn Sie sich nur für die Antwort des Ziels interessieren.

%{http_connect} meldet den Antwortcode des Proxys speziell für den CONNECT-Befehl, getrennt vom Status des Zielservers. Genau diese Unterscheidung benötigen Sie, wenn etwas fehlschlägt und Sie nicht wissen, welche Instanz den Zugriff verweigert hat:

curl -s -o /dev/null -x "$PROXY" \
  -w 'connect=%{http_connect} status=%{response_code} proxy=%{proxy_used}\n' \
  https://example.com

connect=200 status=403 bedeutet, dass der Proxy funktioniert hat und der Zielserver den Zugriff verweigert hat. connect=407 bedeutet, dass der Proxy Anmeldedaten angefordert hat und den Zielserver nie erreicht hat. Diese beiden Situationen erfordern völlig unterschiedliche Lösungen, und ohne diese Unterscheidung sehen sie aus Sicht der Anwendung identisch aus.

Beachten Sie außerdem, dass der Proxy bei HTTPS über einen Tunnel keine Header hinzufügen oder lesen kann – er leitet lediglich verschlüsselte Bytes weiter. Wenn Sie unerwartete Header in einer HTTPS-Antwort sehen, stammen diese vom Zielserver oder von einem davor liegenden CDN, nicht vom Proxy.

Was die Header tatsächlich aussagen

Worum es dabei eigentlich geht: Wenn man sie richtig interpretiert, wird aus Rätselraten eine Diagnose.

Zuerst die Statuszeile. 200 war erfolgreich. 301/302 wurden weitergeleitet. 403 wurde abgelehnt. 429 unterliegt einer Ratenbegrenzung. 407 erfordert eine Proxy-Authentifizierung. 502/503: Probleme mit dem Upstream.

Retry-After erscheint zusammen mit 429 und 503 und gibt genau an, wie lange Sie warten müssen. Die Einhaltung dieser Wartezeit ist sowohl korrekt als auch der schnellste Weg zurück zum normalen Betrieb. Wenn Sie sie ignorieren und es sofort erneut versuchen, wird aus einer vorübergehenden Beschränkung eine länger andauernde.

Content-Type zeigt Ihnen, was Sie tatsächlich erhalten haben. „text/html“ an einem API-Endpunkt bedeutet, dass Sie eine Fehlerseite und kein JSON erhalten haben – dies ist die Ursache für einen Großteil der Parsing-Fehler.

Content-Length im Vergleich zu dem, was angekommen ist. Ein kurzer Body bei einer großen deklarierten Länge deutet auf eine Verkürzung hin.

Cache-Header — Cache-Control, ETag, Last-Modified — geben an, ob Sie ein erneutes Abrufen vermeiden können. If-None-Match und If-Modified-Since bei nachfolgenden Anfragen wandeln eine vollständige Übertragung in eine „304“ um, was bei begrenzter Bandbreite eine direkte Einsparung darstellt.

Set-Cookie zeigt an, welchen Sitzungsstatus der Server herstellt, und das Fehlen dieses Header an einer Stelle, an der Sie ihn erwartet hätten, erklärt viele Rätsel bei der Authentifizierung.

Server und herstellerspezifische Header geben Aufschluss darüber, was sich vor dem Ursprungsserver befindet. Eine Antwort, die Header eines Sicherheitsanbieters mit dem Präfix „403“ enthält, weist darauf hin, dass die Blockierung von einer Schutzschicht und nicht von der Anwendung selbst stammt – ein anderes Problem, das eine andere Reaktion erfordert.

Nicht standardmäßige Header. Ratenbegrenzungsbudgets, Anforderungskennungen und API-spezifische Metadaten erscheinen oft als Header mit dem Präfix „x-“ und sind häufig die nützlichsten Informationen in der Antwort. Eine Anforderungskennung ist das, wonach der Support fragen wird.

Häufig gestellte Fragen

Wie kann ich mit curl die Antwort-Header anzeigen?

curl -i URL zeigt die Header gefolgt vom Request-Body an. curl -D - URL gibt die Header separat über stdout aus. curl -v URL zeigt sowohl die Request- als auch die Antwort-Header an. Vermeiden Sie -I beim Debuggen einer echten Anfrage, da dabei ein HEAD- statt eines GET-Requests gesendet wird.

Was ist der Unterschied zwischen -i und -I in curl?

-i schließt die Antwort-Header zusammen mit dem Hauptteil Ihrer tatsächlichen Anfrage ein. -I sendet stattdessen eine HEAD-Anfrage, es handelt sich also um eine andere Anfrage mit potenziell anderen Ergebnissen. Verwenden Sie -i oder -o /dev/null -D -, wenn Sie die Header der Anfrage benötigen, die Sie gerade debuggen.

Wie kann ich nur die Header ohne den Hauptteil anzeigen?

curl -sS -o /dev/null -D - URL. Dies führt einen normalen GET-Aufruf durch, verworfen den Hauptteil und gibt die Header aus. Damit erhalten Sie das, was -I Ihnen scheinbar liefert, ohne die HTTP-Methode zu ändern – was wichtig ist, da manche Server auf HEAD-Anfragen anders reagieren oder diese gänzlich ablehnen.

Wie kann ich die von curl gesendeten Request-Header anzeigen?

curl -v URL. Suchen Sie nach Zeilen, die mit „>“ beginnen – das sind die von curl gesendeten Header. Die ausführliche Ausgabe wird an stderr gesendet; leiten Sie sie daher mit „2>&1“ weiter, wenn Sie sie filtern möchten. So können Sie überprüfen, ob der von Ihnen konfigurierte Header tatsächlich übertragen wird.

Wie erhalte ich curl-Header als JSON?

curl -s -o /dev/null -w '%{header_json}' URL. Diese in curl 7.83.0 hinzugefügte Option gibt alle Antwort-Header als JSON-Objekt mit Namen in Kleinbuchstaben und Array-Werten aus, sodass wiederholte Header wie „Set-Cookie“ erhalten bleiben und nicht zusammengefasst werden. Leiten Sie die Ausgabe über eine Pipe an „jq“, um Felder zu extrahieren.

Warum sehe ich zwei Sätze von Headern, wenn ich einen Proxy verwende?

Bei HTTPS über einen HTTP-Proxy sendet curl zunächst einen CONNECT, um einen Tunnel zu öffnen, und die Antwort des Proxys darauf erscheint vor der des Ziels. Verwenden Sie --suppress-connect-headers, um diese ausblenden, oder %{http_connect}, um den Statuscode des Proxys getrennt von dem des Ziels auszulesen.

Wie kann ich die Header für jede Weiterleitung anzeigen?

Fügen Sie -L hinzu, damit curl den Weiterleitungen folgt, und verwenden Sie -D - oder -i – curl gibt die Header jeder Antwort in der Kette aus, einen Block pro Hop. %{num_redirects} und %{url_effective} zeigen Ihnen die Anzahl und die endgültige URL in einer einzigen Zeile an.

Verraten die Antwort-Header, ob ich blockiert werde?

Oftmals ja, und zwar zuverlässiger als der Antworttext. Ein 429 mit Retry-After deutet auf eine Ratenbegrenzung hin. Ein 403 mit den Headern eines Sicherheitsanbieters ist eine Schutzebene. Ein 200 mit Content-Type: text/html an einem API-Endpunkt ist eine Challenge- oder Anmeldeseite. Jede dieser Situationen erfordert eine andere Lösung, und nur die Header lassen eine Unterscheidung zu.

Fazit

Vier Optionen und eine häufige Falle. -i für die tägliche Überprüfung, -D -, wenn Sie die Header getrennt vom Hauptteil anzeigen möchten, -v, wenn Sie sowohl sehen möchten, was Sie gesendet haben als auch, was zurückkam, und -I nur für schnelle Erreichbarkeitsprüfungen – da es einen HEAD-Request sendet und Server das Recht haben, auf einen HEAD-Request anders zu antworten als auf einen GET-Request.

Die Option, die es sich lohnt zu übernehmen, wenn Sie nur eine Sache aus diesem Text mitnehmen, ist %{header_json}. Jedes Skript, das derzeit Header-Text mit einem regulären Ausdruck analysiert, sollte stattdessen diese Option verwenden: Namen in Kleinbuchstaben, Arrays für wiederholte Header und eine Ausgabe, die jq lesen kann. In Kombination mit %{response_code}, %{num_redirects} und %{proxy_used} wird die Header-Prüfung zu etwas, das Sie programmatisch überprüfen können, anstatt es nur mit dem Auge zu begutachten.

Und wenn eine Anfrage fehlschlägt, lesen Sie die Header, bevor Sie irgendetwas ändern. Der Statuscode, Retry-After, Content-Type und etwaige Hersteller-Header dazwischen benennen das Problem in der Regel direkt – was besser ist, als Einstellungen so lange auszuprobieren, bis etwas funktioniert, und dauert etwa zehn Sekunden.