0

I have created a site using Create React App on the frontend and Node express on the back. I then hosted React on IIS and ran Node as a windows service on the backend.

When running the app I set my callback paths in React (REACT_APP_HOST) to "localhost" and in the node my routes are "/routeName". This being said, the first path called is ${REACT_APP_HOST}/sitemap and the receiving path on the server is router.use('/siteMap', (req, res, next) => siteMapController(req, res, next));.

On the local server, using it as a client, this works perfectly. On a remote client (same domain) I am getting a 404 error.

The next step I tried was changing REACT_APP_HOST to "", making the resulting call to "/sitemap". This has stopped the functioning even on localhost.

Here is my code (app.js, sitemap fetch and server.js). Hoping that someone can give me a clue as to where I am going wrong.

//app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser')
var logger = require('morgan');
var cors = require('cors');
var nodeSSPI = require('express-node-sspi');
let routeList = require('./routes/routeList');
let FileLoader = require('./Controllers/FileLoader');

var app = express();

app.use(bodyParser.json({ limit: '400000' }));
app.use(cors({
  origin:['http://localhost', 'http://intranet-test', 'http://intranet'],
  credentials: true
}));
app.use(express.static(path.join(__dirname,'../public')));
app.options('*', cors()); // include before other routes
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

//https://www.npmjs.com/package/yarn 
app.use(nodeSSPI({
  retrieveGroups: false,
  offerBasic: false,
  authoritative: true,

}));

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

routeList(app);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  console.log(req.originalUrl);
  console.log(req.method)
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  console.log(err);
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
//sitemap fetch
export const fetchInit = () => {
    return ({
        method: 'GET'
        , headers: {
            'Content-Type': 'application/json'
        }
        , credentials: 'include'
    })
};

export const Sitemap_Fetch = () => (dispatch) => {
    dispatch({
        type: ActionTypes.SITEMAP_LOADING
    });
    var myReq = new Request(`${process.env.REACT_APP_HOST}/siteMap`, fetchInit());//?' + params

    return fetch(myReq)
        .then((response) => {
            // if (response.ok) {
            return response;
            // }
            // else {
            //     var error = new Error("Error " + response.statusText);
            //     error.response = response;
            //     throw error;
            // }
        },
            (error) => {
                var err = new Error(error.message);
                throw err;
            }
        )
        .then(response => response.json())
        .then((data) => {
            try {
                dispatch({
                    type: ActionTypes.SITEMAP_LOADED,
                    payload: data
                })
                return data;
            }
            catch (ex) { throw ex }
        })
        .catch((err) => {
            return dispatch({
                type: ActionTypes.SITEMAP_FAILED,
                payload: err.message
            })
        });
}
//server.js
#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('./app');
var debug = require('debug')('node-backend:server');
var http = require('http');


/**
 * Get port from environment and store in Express.
 */

var port = normalizePort('3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port, '0.0.0.0');
server.on('error', onError);
server.on('listening', onListening);
server.on('request',test=>{console.log(test)})
/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  console.log(addr)
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
  console.log('Listening on ' + bind);
}

Finally I am adding the .env file from my React site

BROWSER=none
SKIP_PREFLIGHT_CHECK=true
REACT_APP_HOST=http://localhost
PORT=80

This works as is. When I change REACT_APP_HOST to nothing it stops functioning.

THanks.

9
  • Did you check the browser console for errors? Also, process.env.REACT_APP_HOST probably returns undefined. Try something like ${process.env.REACT_APP_HOST || ''}/siteMap Commented Sep 19, 2022 at 16:31
  • Also when changing env variables you need to restart node to make sure it sees the new value. Commented Sep 19, 2022 at 16:38
  • @WPW Node was restarted. I ran it from the command line while testing so I could see the console. There were no messages from it. Also node is not using any environment variables, they are all on the React side and included during build. Commented Sep 19, 2022 at 16:41
  • @wobsoriano I will make those changes, but the network headers show it's trying to call 'Request GET /siteMap HTTP/1.1'. The console gives no errors that I can see beyond the Redux Logger: "%c action %cSITEMAP_FAILED %c@ 08:58:04.503" Commented Sep 19, 2022 at 16:45
  • 1
    @long_hair_programmer Is there any way then to get the IP without having to manually code it then? Currently it is running on a test machine and will be migrated to live at some point in the future and we don't want to have to continually rebuild each time. I had thought that retrieving the page from "intranet_test" (which works) would give me the same results using "/siteMap". That is it would give me "intranet_test/siteMap" would it not? Just figured it out. It's a port setting. Node is running on 3000 so I need to create a reverse proxy. Thanks for the idea. Commented Sep 19, 2022 at 19:35

1 Answer 1

0

What I have done to solve this is use the serve (https://stackoverflow.com/a/49209041/2242131) command from a simple batch file and run my node backend from another batch. Then in React I created a constant called "hostname" which I set to ${window.location.hostname}:3000. This is now consistently serving my pages the necessary data.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.