JSON POST-Request mit Python requests senden

requests.post(url, json=payload) sendet einen JSON-Body in einer einzigen Zeile an einen Server. Das json=-Argument serialisiert das Dictionary, setzt den Content-Type: application/json-Header und schreibt den Request-Body. Die Antwort liefert einen Statuscode und bei den meisten APIs die gespeicherten Daten, wodurch der Erfolg des Aufrufs bestätigt wird. Dies ist das Muster hinter REST-API-Schreiboperationen, Webhooks und Endpunkten, die eine JSON-Nutzlast erwarten.

Python requests.post Beispiel für JSON

Ausgabe:

Die Ausgabe erscheint hier...

Ausgabe:

Status: 201
Server stored: {'language': 'Python', 'stars': 3, 'id': 101}

So Funktioniert Dieses Beispiel

  1. json= serialisiert das Dictionary und setzt Content-Type: application/json, sodass der Server ein JSON-Objekt statt Formularfelder empfängt.
  2. timeout=10 begrenzt die Wartezeit, sodass ein nicht erreichbarer Endpunkt schnell scheitert statt den Lauf zu blockieren.
  3. raise_for_status() wandelt eine 4xx- oder 5xx-Antwort in eine Exception um, sodass eine fehlgeschlagene Antwort nie lautlos weiterläuft.
  4. response.json() gibt die Antwort als Python-Dict zurück. Diese Test-API gibt Ihre Felder zurück und fügt eine server-seitige id hinzu; der Status 201 Created bestätigt, dass der Aufruf als neue Ressource behandelt wurde.

Prüfen, Was der Server Tatsächlich Empfing

Zwei unabhängige Signale bestätigen, dass der POST funktioniert hat; eine zuverlässige Prüfung nutzt beide. Der Antwort-Body beweist, dass der Inhalt ankam: zurückgegebene Felder plus eine neue id bedeuten, dass der Server Ihr JSON geparst hat. Run Details beweist den Transport: Es zeichnet auf, was der Browser tatsächlich gesendet hat.

Run Details-SignalWas es bestätigt
Ein POST auf jsonplaceholder.typicode.com, Status 201Der Request ging als POST ab und der Server hat eine Ressource erstellt
Die Methoden-Spalte zeigt POST, nicht GETrequests.post sendete das gewünschte Verb
Die Request-Dauer in msRound-Trip-Zeit, separat vom JSON-Parsing
Status blockiert oder fehlgeschlagen, ohne HTTP-CodeDer Request hat den Server nicht erreicht (siehe CORS unten)
Packages listet requestsweb.run hat das gebündelte requests-Paket beim Import geladen

Wenn der Statuscode 2xx lautet, aber der zurückgegebene Body Ihre Felder fehlen lässt, war der Transport erfolgreich, der Inhalt nicht. Diese Unterscheidung können die meisten POST-Tutorials nicht zeigen, weil sie gesendeten Request und Server-Antwort nie nebeneinander stellen.

json vs data: Der Stille Datenverlust-Bug

Dieselbe Nutzlast mit data= statt json= senden — der Server antwortet trotzdem mit 2xx, aber der zurückgegebene Body enthält keine Ihrer Felder. Der Request war in Ordnung; die Kodierung war falsch.

ArgumentWas requests sendetWas der Server parst
json={"stars": 3}JSON-Body und Content-Type: application/jsonein JSON-Objekt
data={"stars": 3}form-encodierter Body und application/x-www-form-urlencodedFormularfelder, kein JSON
data=json.dumps({"stars": 3})ein roher JSON-String ohne JSON-HeaderText, den er möglicherweise nicht als JSON parst

Faustregel: Übergeben Sie ein Dictionary an json= für jede API, die einen JSON-Body erwartet, und verwenden Sie data= nur beim Absenden eines HTML-Formulars. Eine JSON-API, die Form-Encoding empfängt, antwortet meist mit 2xx und verwirft die Daten still, weshalb die Prüfung des Statuscodes allein nie ausreicht.

Wann ein Browser-POST Blockiert Wird, Nicht Abgelehnt

Ein Cross-Origin-POST verhält sich im Browser anders als in einem Server-Skript. Da der Body application/json ist, sendet der Browser vor dem POST einen CORS-Preflight OPTIONS. Wenn der Endpunkt nicht die passenden Access-Control-Allow-Origin- und Access-Control-Allow-Headers-Header zurückgibt, blockiert der Browser den POST, bevor er abgeht.

In diesem Fall wirft requests einen Connection Error wie requests.exceptions.ConnectionError, kein HTTPError, und Run Details markiert den Request als blockiert oder fehlgeschlagen ohne HTTP-Status. Ein 403 oder 422 ist das gegenteilige Signal: Der Request hat den Server erreicht, der ihn ablehnte.

Regel: kein HTTP-Status bedeutet ein Netzwerk- oder CORS-Problem vor dem Server; ein HTTP-Status bedeutet, der Server hat geantwortet, auch wenn er mit einem Fehler geantwortet hat. jsonplaceholder ist CORS-fähig, daher sendet das Beispiel sauber. Viele öffentliche APIs sind es nicht, weshalb identischer requests.post-Code im Terminal funktionieren, aber in diesem Runtime oder jedem In-Browser-Python scheitern kann.

Häufige Fehler

Fehler: Ein Dictionary mit data= senden, wenn die API JSON erwartet.

Falsch:

requests.post(url, data={"stars": 3})

Richtig:

requests.post(url, json={"stars": 3})

Warum es passiert: data= form-encodiert das Dictionary und setzt einen Form-Content-Type, sodass eine JSON-API kein JSON-Objekt erhält und Ihre Felder aus dem Ergebnis fallen.

Fehler: Den Body doppelt serialisieren.

Falsch:

requests.post(url, json=json.dumps({"stars": 3}))

Richtig:

requests.post(url, json={"stars": 3})

Warum es passiert: json= serialisiert den Wert bereits. Einen vorbereiteten String zu übergeben, kodiert ihn doppelt zu einem JSON-String statt einem Objekt.

Header und Auth Mit dem POST Senden

Die meisten Write-APIs erfordern Authentifizierung, die in den Request-Headern neben dem Body mitgegeben wird:

response = requests.post(
    url,
    json=payload,
    headers={"Authorization": "Bearer TOKEN"},
    timeout=10,
)

requests fügt Ihre Header mit dem Content-Type zusammen, den es für json= setzt; Sie geben nur die API-spezifischen an. Nie ein echtes Token in geteiltem Code hart kodieren — aus einer Umgebungsvariable lesen. Ein benutzerdefinierter Header wie Authorization reicht bereits aus, um den oben beschriebenen CORS-Preflight auszulösen. Für die passende Leseseite siehe JSON von einer URL lesen, und wickeln Sie den Aufruf in try/except ein, um Verbindungsfehler zu behandeln.

FAQ

Wie sendet man einen POST-Request in Python?

Rufen Sie requests.post(url, json=payload) mit einem Dictionary als Nutzlast auf. Das json=-Argument serialisiert das Dictionary, setzt den Content-Type: application/json-Header und sendet alles in einem Aufruf. Lesen Sie die Antwort mit response.json().

Warum gibt mein POST 200 zurück, aber der Server ignoriert die Daten?

Der Body wurde im falschen Format gesendet, meist als Formularfelder über data= statt JSON über json=. Der Server antwortet 2xx auf den Request selbst, parst aber nie ein JSON-Objekt. Wechseln Sie zu json= und prüfen Sie, ob der Server Ihre Felder zurückgegeben hat.

Warum wird mein requests-POST im Browser blockiert?

Ein Cross-Origin-JSON-POST löst einen CORS-Preflight aus. Wenn der Endpunkt nicht Access-Control-Allow-Origin und Access-Control-Allow-Headers zurückgibt, blockiert der Browser den Request, bevor er abgeht; requests wirft dann einen Connection Error ohne HTTP-Status statt einem 4xx. Derselbe Code kann im Terminal noch funktionieren.

Was ist der Unterschied zwischen json und data in requests.post?

json= serialisiert ein Dictionary zu einem JSON-Body und setzt Content-Type: application/json. data= sendet form-encodierte Felder oder einen rohen String ohne JSON-Header. Verwenden Sie json= für JSON-APIs und data= für HTML-Formular-Submissions.