I have an index.html EJS rendered by a koa/Node.js app which contains a javascript snippet to post data about the current page to the same app, to an endpoint to save in a database.
The javascript code ( an AJAX fetch POST
) reaches the Node.js endpoint but doesn’t transmit any data. I don’t see any typo in the code.
# index.js
const Koa = require("koa");
const path = require("path");
const render = require("koa-ejs");
const bodyParser = require("koa-bodyparser");
const router = require("./routes/routes.js");
const app = new Koa();
render(app, {
root: path.join(__dirname, "/views"),
layout: false,
viewExt: "html",
});
app
.use(bodyParser())
.use(router.routes())
.use(router.allowedMethods())
.use(staticCache("./images", { maxAge: 600000 }))
.listen(PORT, () => {
console.log(`Running on port ${PORT}`);
});
In the index.html, I have a button that triggers a POST request to an endpoint (/node/insert
) of the koaRouter. The action is to save information about the current page (say, document.location.href
) in a Postgres database.
# /views/index.html
[...]
<form id="newRow">
<input type="submit" value="New row">
</form>
[...]
<script type="module" src="fetch.js" async></script>
where:
# /views/fetch.js
const data = {
app: "Node",
url: document.location.href,
...
};
document.getElementById("newRow").addEventListener("submit", (e) => {
e.preventDefault();
fetch("/node/insert", {
method: "POST",
headers: {
"Content-Type": "application/json; charset-UTF-8",
},
body: JSON.stringify(data),
})
.then((res) => {
if (res.ok) {
return res.json();
}
return Promise.reject(res);
})
.then((res) => console.log("front", res))
.catch((err) => console.warn(err));
Among the routes, I defined an endpoint /node/insert
to respond to this action:
# routes.js
const koaRouter = require("koa-router");
const router = new koaRouter();
router.post("/node/insert", async (ctx) => {
console.log("posted", ctx.request.body);
^^^ "posted" is positively printed in terminal after submit
if (ctx.request.body) {
return (ctx.response.status = 200)
} else {
return (ctx.response.status = 404); <-- check
}
})
The endpoint "/node/insert" is reached since I can console.log positively, but the body isn’t passed to the endpoint: ctx.request.body = {}
. I have the following error:
"SyntaxError: Unexpected token O in JSON at position 0"
detected from fetch.js (probably because the body is {}
?).
I don’t see what is wrong.
Note: the Node app runs in a container (
pm2-runtime start index.js
) and use Nginx as reverse proxy, static files server and load-balancer`
2
Answers
Just a typo in the bodyparser as Evert pointed and bad positioning of the middleware
curl --data "app=Node" HTTP://localhost:8000/node
responds normaly.Try: