简体   繁体   中英

Express POST returns 404 on Apache

There is a React app that has express requesting api/login information from Mongodb and checking the password input against it, otherwise it doesn't allow you to access the website.

Locally everything works great. When we moved all the build files to the apache server the console returns POST https://websitepath.com/api/login 404 (Not Found)

在此处输入图片说明

Any idea of what could be a problem and why it works locally but doesn't work on apache? Node is installed and Express is running there successfully on port 4000.

Here is the code for index.js

var express = require('express');
var bodyParser= require('body-parser')
var MongoClient = require('mongodb').MongoClient
var sha1 = require('sha1');
var db;

const PORT = 4000;
var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));


app.use('/api/login', function (req, res) {

  if (!req.body.password) return res.status(400).send('bad_request!')

  db.collection('user').find().toArray(function(err, results) {
    if (err) return res.status(500).send('something_wrong!');

    var checker = false;

    results.forEach(function (entry) {
      if (entry.password === sha1(req.body.password)) checker = true;
    })

    if (checker) {
      res.send('success')
    } else {
      return res.status(403).send('Unfortunately password is incorrect. Please try again.');
    }
  })
})

MongoClient.connect('mongodb://localhost:27017/test', (err, database) => {
  if (err) return console.log(err)
  db = database
  app.listen(PORT, function() {
    console.log('Express server is up on port ' + PORT);
  });
})

Here is the code for the AuthService.js

 import axios from 'axios';
import qs from 'qs';

const AuthService = {
  isLogged: false,
  login(data, cb) {

    axios.post('/api/login',  qs.stringify(data)).then(
      (res) => {
        this.isLogged = true;
        cb(null, res);
      }
    ).catch((error) => {
      console.error('error occured', error);
      cb(error.response.data);
    })
  },
}

export default AuthService;

Your question doesn't mention proxying the node.js application, so I'm guessing that's where the problem is - specifically, the node application is not being proxied.

In short, what you appear to be trying to do is something like this:

Apache is listening on port 443 (the HTTPS port) and serving web pages at various paths (presumably, everything except paths starting with /api ).

You want the web server to also serve the paths used by your node.js API (eg. /api/login and others) on port 443.

But two distinct applications (Apache and your node.js app) cannot both listen on port 443 - Apache is binding it and serving its own pages. If you try to change the port on your node.js application, it will fail to start and give you an error indicating that port 443 is already bound by another application.

There is a simple test for this: navigate to http://websitepath.com:4000/api/login . If you can see your API login page (ie. the node.js application is listening on port 4000), that means the problem is NOT with your node application, it's with Apache's proxy configuration.

The solution to this is setting up Apache as a proxy . This will allow Apache to serve its own pages and forward the request to another service based on the path. So you could certainly set it up so paths that start with /api/... are forwarded to http://localhost:4000/api/... and any other paths are served by Apache directly.

Setting up a proxy is not terribly difficult, but it depends a lot on your specific circumstances, so I'm not going to attempt to explain all the ins & outs. I'd recommend starting with the mod_proxy documentation. There are also about a million tutorials out there; Digital Ocean's documentation is good - I've used it in the past.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM