405 Error for POST request

I'm working through a Coding Train tutorial on data and APIs, but I got to a point where I keep getting a 405 error when trying to make a POST request. index.js:
const express = require('express');
const app = express();
app.listen(3000, () => console.log('listening at 3000'));
app.use(express.static('public'));
app.use(express.json({ limit: '1mb' }));
app.post('/api', (request, response) => {
console.log(request.body);
response.json({ message: 'POST request received' });
});
const express = require('express');
const app = express();
app.listen(3000, () => console.log('listening at 3000'));
app.use(express.static('public'));
app.use(express.json({ limit: '1mb' }));
app.post('/api', (request, response) => {
console.log(request.body);
response.json({ message: 'POST request received' });
});
script inside index.html:
if ('geolocation' in navigator) {
console.log('geolocation available');
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude, position.coords.longitude);
const lat = position.coords.latitude.toFixed(2);
const lng = position.coords.longitude.toFixed(2);
const latDisp = document.getElementById("lat");
const lngDisp = document.getElementById("lng");
latDisp.innerText = lat;
lngDisp.innerText = lng;

const data = { lat, lng };
const options = {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data)
};
fetch('/api', options);
});
} else {
console.error('geolocation IS NOT avaiable');
}
if ('geolocation' in navigator) {
console.log('geolocation available');
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude, position.coords.longitude);
const lat = position.coords.latitude.toFixed(2);
const lng = position.coords.longitude.toFixed(2);
const latDisp = document.getElementById("lat");
const lngDisp = document.getElementById("lng");
latDisp.innerText = lat;
lngDisp.innerText = lng;

const data = { lat, lng };
const options = {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data)
};
fetch('/api', options);
});
} else {
console.error('geolocation IS NOT avaiable');
}
In the console I get: geolocation available [my lat] [my lng] POST http... net::ERR_ABORTED 405 (Method Not Allowed) If I go to Network in the dev tools in Chrome and open the item with the error I can see that the Response Headers > Allow: GET, HEAD, OPTIONS. I'm not sure why POST is not allowed. Any help would be greatly appreciated. Thanks!
65 Replies
Jochem
Jochem2w ago
POST is generally used to make changes on the remote server, not to request data 99% of the free APIs out there are read-only, so they don't tend to use POST as a method at all I'm unfamiliar with the tutorial, but are you sure it's using POST in the example code? Also, as all HTTP errors, a 405 error is a server side error. Unless you control the API, you will have to check the documentation for the API to see what is and isn't allowed at that end point and adjust your own code accordingly
StefanH
StefanH2w ago
They're using their own nodejs server
Jochem
Jochem2w ago
oh! I missed that part, oops
🎺Mathew
🎺MathewOP2w ago
that's true, I'm both server and client for this project
StefanH
StefanH2w ago
I don't know express but i don't see anything wrong right away
Jochem
Jochem2w ago
same, nothing super obvious at least have you restarted the express server?
🎺Mathew
🎺MathewOP2w ago
I'm using nodemon it restarts regularly should I manually restart it?
ἔρως
ἔρως2w ago
try sending a get request and see what happens
Ganesh
Ganesh2w ago
Why are you listening the server before defining the middleware
Jochem
Jochem2w ago
yeah
ἔρως
ἔρως2w ago
also, the post is after the listen too
Ganesh
Ganesh2w ago
Not sure if that makes a difference with express's implementation but usually you listen at the very end
Jochem
Jochem2w ago
might not help, but it's pretty much free to test and restarting shit solves 90% of all issues
ἔρως
ἔρως2w ago
(ignore the low fps) (and the misspells)
Ganesh
Ganesh2w ago
Also a note that with latest node version, nodemon isn't needed Just use the --watch option
🎺Mathew
🎺MathewOP2w ago
I manually restarted it, same issue
ἔρως
ἔρως2w ago
move the listen to the end
🎺Mathew
🎺MathewOP2w ago
moved listen to the end, same 405 error
ἔρως
ἔρως2w ago
send a get request
13eck
13eck2w ago
--watch was introduced in Node v18, back in 2022. Stable in Node 20, back in 2023 😉
Ganesh
Ganesh2w ago
Can you post the console error output here if you get 405 again
🎺Mathew
🎺MathewOP2w ago
index.html:32 POST http://127.0.0.1:5500/api net::ERR_ABORTED 405 (Method Not Allowed) (anonymous) @ index.html:32
13eck
13eck2w ago
There's your problem
Ganesh
Ganesh2w ago
I know but I can't be bothered to look up the date so saying latest version is a good bet. Tho i actually meant lts. Keep confusing latest and lts
13eck
13eck2w ago
You're posting to port 5500 but the server is listening on port 3000 Yep. That's why I did the hard work 😉
Ganesh
Ganesh2w ago
I welcome the service
13eck
13eck2w ago
I'd suggest typing out the entire URL, not doing relative, when using localhost
🎺Mathew
🎺MathewOP2w ago
probably a dumb question, how do I change what port I'm posting at?
13eck
13eck2w ago
// your code:
fetch('/api', options);
// edits:
fetch('localhost:3000/api', options);
// your code:
fetch('/api', options);
// edits:
fetch('localhost:3000/api', options);
🎺Mathew
🎺MathewOP2w ago
new error "localhost" is not supported
13eck
13eck2w ago
try http://localhost:3000/api
ἔρως
ἔρως2w ago
i see the problem you have to specify the full api url
Ganesh
Ganesh2w ago
Might also have to explicitly put the ip address instead of localhost if it says cors has blocked request
13eck
13eck2w ago
Frickin' CORS 😡
🎺Mathew
🎺MathewOP2w ago
I'm using live server in VS code at port:5500. Is that a problem?
Ganesh
Ganesh2w ago
No that's okay
ἔρως
ἔρως2w ago
you're sending the request to /api, which is a relative path to the root of the live version but you're hosting it in a different "host" (port) you have to do this: specify the FULL url with port you can't just do /api, because it will send the request to the server hosting the website instead
🎺Mathew
🎺MathewOP2w ago
index.html:1 Access to fetch at 'http://localhost:3000/api' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. do I need to add something to the headers in options?
ἔρως
ἔρως2w ago
you have to send headers for cors from the server, and you have to request cors from the fetch
13eck
13eck2w ago
Or set the IP instead of localhost
ἔρως
ἔρως2w ago
that'll be the same because the port is different, it's another host also, 127.0.0.1 and localhost are not the same origin for this
Ganesh
Ganesh2w ago
Yeah he will need the cors middleware Actually not even middleware if we're just doing a single endpoint. Just set it on response I'm actually wondering Is the tutorial actually means you to server html file from the public directory? You have express static in the code
13eck
13eck2w ago
I was wondering about that, too. They're using the static middleware so the server should be serving it and not VS Code This here seems to be the problem. Turn off VS Code server and let your Express server do it Then it's on the same origin and it'll work fine
Ganesh
Ganesh2w ago
We'll need the file structure first To confirm they actually have html in public folder
13eck
13eck2w ago
I would hope the tutorial would show how to setup the file structure properly lol
Ganesh
Ganesh2w ago
Me too but i dunno what the tutorial intended lol
🎺Mathew
🎺MathewOP2w ago
static index.html is in the public folder how do I 'let Express server do it'
ἔρως
ἔρως2w ago
you run node from the console
13eck
13eck2w ago
You already are:
app.use(express.static('public'));
app.use(express.static('public'));
Ganesh
Ganesh2w ago
http://127.0.0.1:3000/
http://127.0.0.1:3000/
Is where your server is running If you type
http://127.0.0.1:3000/index.html
http://127.0.0.1:3000/index.html
in browser url bar it should serve the html file
ἔρως
ἔρως2w ago
you forgot the // part
Ganesh
Ganesh2w ago
Ahh dammit
ἔρως
ἔρως2w ago
still wrong it's ://, not //:
🎺Mathew
🎺MathewOP2w ago
it worked! thanks so much! you guys are the best!
13eck
13eck2w ago
We're ok, I guess 🤷
🎺Mathew
🎺MathewOP2w ago
I still have a lot to learn
13eck
13eck2w ago
You're in the right place to keep learning
🎺Mathew
🎺MathewOP2w ago
any recommendations for tutorials I should follow for learning backend
Ganesh
Ganesh2w ago
Keeps happening
ἔρως
ἔρως2w ago
it's fine i have almost 19 years of programming in my belt, but i still have a lot to learn
13eck
13eck2w ago
Not really sure. I learned most of Nodejs by reading the docs. A lot of tutorials will start with npm i <a long list of packages> so they don't actually teach you Nodejs, they teach you how to use other people's packages. For example, you really don't need Express in 2025. Nodejs has 90% of it already covered, except for serving static files, and even then that's really easy to do 🤷
Ganesh
Ganesh2w ago
MDN Web Docs
Server-side website programming - Learn web development | MDN
The Dynamic Websites – Server-side programming topic is a series of modules that show how to create dynamic websites; websites that deliver customized information in response to HTTP requests. The modules provide a general introduction to server-side programming, along with specific beginner-level tutorials on how to use the Django (Python) an...
Ganesh
Ganesh2w ago
This might be okay Note i haven't taken it but at a cursory glance it seems fine Just ignore the non node js parts like django
🎺Mathew
🎺MathewOP2w ago
thanks again!

Did you find this page helpful?