I have a frontend react
that uses axios
to get data from a separate node
server. The frontend uses a .app
domain with SSL certificate but the backend http://localhost:3001
, vanilla http, IP address, and port.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
…
axios({
method: 'GET',
url: 'http://localhost:3001/',
params: {page: pageNumber, limit: limit},
cancelToken: new axios.CancelToken(c => cancel = c)
}).then( res => {
setSermons( prevSermons => {
return [...new Set([...prevSermons, ...res.data.map( sermon => sermon )])]
})
setHasMore(res.data.length > 0)
setLoading(false)
}).catch( e => {
if (axios.isCancel(e)) return
setError(true)
})
return () => cancel()
}, [query, pageNumber, limit] )
… and here is my backend node/express server:
const express = require('express')
const cors = require('cors')
const knex = require('knex')
require('dotenv').config()
const db = knex({client: 'pg', connection: <...connection stuff...>})
const app = express()
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
app.use(cors())
app.get('/', (req, res) => {
let page = req.query.page || 0
let limit = req.query.limit || 50
db.select('*')
.from('sermons')
.limit(limit, {skipBinding: true})
.offset(limit*page)
.then( (data) => {
res.json(data)
})
.catch( (err) => {
console.log(err)
})
})
const port = process.env.APP_PORT
app.listen(port, '0.0.0.0', () => console.log(`Server running on port ${port}, http://localhost:${port}`));
I can open both the frontend and backend parts of the site on my browser. The backend is accessible via http://157.xxx.xxx.xxx:3001 IP and the frontend maps to my domain. But the frontend can’t retrieve data from the backend.
All of this is running behind an nginx
reverse proxy. I did not find any firewalls installed on the server. Yesterday it was working but overnight the connection refused error started. I know that previously, I left the localhost out of the nginx setup entirely.
It seems like CORS is not working, even though the node server is importing/using it. What more can I look at to debug this?
3
Answers
Turns out I couldn't get the backend server to work with http://localhost:3000 but it did work if I mapped it to a true external API with https. This is the final configuration that worked:
nginx.conf
file for JUST the backend server. Previously it was absent fromnginx.conf
because I was trying to make it a localhost only endpoint.How the frontend react app uses
axios
to talk to backend. The backend endpoint is now HTTPS, with a separate, valid SSL certificate for that the<api.mydomain.com>
subdomain:changes to my
node/express
backend server endpointI think many of these changes were not needed, but this is a working state, over https.
Next I'll see if I can block access to this backend to everyone except the frontend domain.
try adding
"proxy": "http://localhost:3001"
to your package.jsonit will proxy your backend and resolve CORS issues. You can read more about it in this blog post:
https://medium.com/bb-tutorials-and-thoughts/react-how-to-proxy-to-backend-server-5588a9e0347
it does sound like a Cors problem
here is a quick video explaining on how cors works
https://www.youtube.com/watch?v=4KHiSt0oLJ0&ab_channel=Fireship
try adding a proxy in the package.json or set a header like this