So, I’m trying to post a JSON to a Node.JS server running Express with Python using the "requests" module. I’ve made a lot of tries, all of them failed.
Closest I got was this:
Server code:
const fs = require('fs');
const express = require('express');
const app = express();
app.use(express.static("public"));
app.use(express.json());
app.get('/', function(_, res) {
var data = fs.readFileSync("./get.json");
res.json(JSON.parse(data));
});
app.post('/', function(req, res) {
fs.writeFile('./get.json', JSON.stringify(req.body), err => {
if (err) {
res.json(JSON.parse('{"status":false,"err":"%s"}', (err)));
} else {
res.json(JSON.parse('{"status":true}'));
};
});
});
app.listen(3000, function() {
console.log(`Up and running on port 3000.`);
});
Python script:
import requests
data = {'test':'Hello World!'}
response = requests.post("XXXXX.herokuapp.com/", data=data)
It sort of works, but on a GET request, it returns a blank JSON ({}), same when logging req.body on the POST request. I want it to return what was sent in the POST request ({'test':'Hello World!'}).
>Solution :
Passing the data keyword arg does not convert the data to JSON. Instead use the json keyword arg. This will convert your dictionary to a JSON serialized string that the server can parse.
import requests
data = {'test':'Hello World!'}
response = requests.post("XXXXX.herokuapp.com/", json=data)
What’s the difference? We can see what happens by looking at the PreparedRequest object that is created before the request is sent.
import requests
### using data param
req = requests.Request('POST', 'http://localhost:8000', data={'test': 'hello world'})
preq = req.prepare()
preq.body
# returns:
'test=hello+world'
req = requests.Request('POST', 'http://localhost:8000', json={'test': 'hello world'})
preq = req.prepare()
preq.body
# returns:
b'{"test": "hello world"}'
The first is not parsable as JSON, where the second is proper JSON.