cannot post ; post can't be made with axis on react - node.js

I am trying to make a post request in React to the server
my React app is running at port 3000 & express app is running at port 9000
React:
axios.post("/").then((response)=>{
console.log(response.data)
}).catch((e)=>{
console.log(e.response.data)
this.out = e.response.data
})
Express:
app.post("/", (req, res) => {
console.clear()
console.log(req.body)
res.end("req")
})
on the web console it says :
"Failed to load resource: the server responded with a status of 404 (Not Found)"
on the app 'postman' It runs just fine
I tried to follow this YT tutorial https://www.youtube.com/watch?v=kJA9rDX7azM

First you need to check weather you add a proxy in your React APP project Package.Json file under the private dependency name,
proxy:
'http://localhost:9000/'
Axios first look for the port you are requesting for in the current server which is in you case is / so / is also a port in frontend so it never goes for the backend be safe to go with
axios.post("http://localhost:9000/")
.then((response)=>{
console.log(response.data)
})
.catch((e)=>{
console.log(e.response.data)
})
Secondly make sure you must install the axios dependency in your react project

Seems like you forgot to add domain in the axios request.
axios.post("http://localhost:9000/").then((response)=>{
console.log(response.data)
}).catch((e)=>{
console.log(e.response.data)
this.out = e.response.data
})

Related

how to prepare ReactJS to upload on online host?

so i have a webapp built with react in front and nodejs express in backend,
i've changed localhost address from 'http://192.168.1.17:333/api/v1?name=test' to 'domain.com/api/v1/test?name=test'
and in backend i've changed port to default like this:
app.listen(() => {
console.log(`server is running`);
})
but when im gonna test my webapp it returns error like this in browser console:
xhr.js:210 POST domain.com/api/v1/test?name=testnet::ERR_FAILED 500
what should i do?
im using axios to post request btw.

Cloud9: "Invalid host header" on React & nodejs app

Im developping a Reactjs & nodejs webapp on AWS's cloud9.
My problem is that i struggle to make a HTTP request from Reactjs frontend to my express backend server.
Both back and front run well separately.
React run on port 8080 and express on port 8081.
Here is the frontend request:
async function getAccessToken(){
await axios.get('/api/token',{
keepAlive: true}).then(function(response){
response.json().access_token;
}).catch(function(error){
console.log('Error dans App.js: ', error);
});
}
Heres the server :
const secureServer = https.createServer({passphrase:process.env.PASSPHRASE, cert: certfile, key: keyfile,}, app);
secureServer.listen(process.env.PORT_SERVER, console.log('Server started on port', process.env.PORT_SERVER));
When i start both and access the application preview, i get an "Invalid host header".
So i searched here, and i dont want to mess with react-scripts webpack.config.js.
I tried to set a "proxy": http://0.0.0.0:8081 in react package.json, to no avail.
Im at a loss here and hope someone can help.
Thanks in advance.

Stop statically served React app from calling server path

My app has the default homepage at "/", and a contact page at "/contact". When I ran the react server(localhost:3000) and express server(localhost:8000) separately, the navigation between these pages works fine as handled by "react-router-dom" below.
Frontend React, Routing.tsx:
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Contact from "../pages/Contact/Contact";
import Main from "../pages/Main/Main";
import Error from "../pages/Error/Error";
function Routing() {
return (
<BrowserRouter>
<Switch>
<Route path="/error" component={Error} />
<Route path="/contact" component={Contact} />
<Route path="/" component={Main} />
</Switch>
</BrowserRouter>
);
}
export default Routing;
Now I built the react app using npm run build, and placed the "build" folder inside my backend express server to be served, as per deployment doc here. Then I ran "npm run dev" to start the server.
However, whenever I try to navigate to the /contact page, it issues a server call to "localhost:8000/contact" instead of being handled by the frontend routing. Of course the server doesn't have that route, and all my server routes are prefaced with "/api/" anyway.
How can we prevent frontend navigation from calling the server routes?
More code below, thanks.
Backend Express, App.ts:
import express from "express";
import path from "path";
class App {
private _app: express.Application;
private readonly _port: number | string = process.env.PORT || 8000;
constructor(controllers: any[]) {
this._app = express();
this.initializeControllers(controllers);
this.initializeMiddleWares();
this.initHostingReactUI();
}
public start() {
this._app.listen(this._port, () => {
console.log(`App listening on the port ${this._port}`);
});
}
private initializeControllers(controllers: any[]) {
controllers.forEach((controller) => {
this._app.use("/api", controller.router);
});
}
public initializeMiddleWares() {
require("./src/middleware/express.middleware")(this._app);
}
public initHostingReactUI() {
// I am aware that you can do "/*" below to catch all routes, but that doesn't solve my issue as it still calls the backend for every non-api routes that should be handled by frontend routing.
this._app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "build", "index.html"));
});
}
}
export default App;
Backend Folder structure with Build folder:
If needed:
Backend github source.
Frontend github source
There are two ways to combine the routes between the frontend and backend:
If access from http://localhost:3000
You need to boot both frontend and backend.
In this case, all your backend request urls will start with http://localhost:3000 (if you didn't specify a base url). To solve this issue, add a line in the root of your client-side package.json file:
{
"proxy": "http://localhost:8000"
}
After that, frontend will redirect all the unknown routes to backend.
If access from http://localhost:8000
You only need to boot the backend.
Since React application is one-page application, which means there is only one html entry (index.html). Now we need a route to serve the frontend routes in the backend:
// place this in the end after the other routes
app.get('*', (req, res) =>
res.sendFile(path.join(__dirname, "build", "index.html"));
})
The routing system will check if the route exists among the backend routes. If not, then serve index.html and check if the route exists among the frontend routes. Therefore, in the frontend you should guard the urls by returning a 404 page when not found.
Do you mean navigate through the app? if not, navigating to the page by the URL or refreshing the page always will send a request to the server, which should return the app index.js.
All you need to do is to place the last route which is serving react (You can use app.get('*', .....) or placingapp.use((req, res) => {...}) without route).
In this case, when the request came to the server, the server will search for the route top-to-bottom, if the requested route is not api then it's will serve the client-side app.

How do I connect React native app with node js?

I have already created backend using node js for sigin & signup page. Now I want to connect to node js . But i have no idea how to do that. I want to connect both react native with my node js. Can you help me ?
simply as how we do for web apps.
here is an example of error reporting
export default async function (body) {
console.log(JSON.stringify(body))
const res = await fetch(`${host}/api/report`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})
const { message } = await res.json()
if (message) return Toast({ message: message });
else return Toast({ message: 'network error' });
}
I have used fetch to send a POST request to my nodejs server
use API tool like postman or other and make your your nodejs APIs works fine and then connect to your React Native app as above.
You can use ngrok to connect Node with react-native. Run this command:
npm i ngrok -g # installing it globally
Then open another terminal. Run:
ngrok http 3000 # the port you are running on node
Then it will show an alternative link that you can use to test with your Node.
Note: if ngrok http 3000 doesn't work, try ngrok http -region us 3000.
The available ones are us, eu, ap, and au. In my case eu worked for me.
Then copy the link generated e.g. http://8074-129-205-124-100.eu.ngrok.io and test your backend if it displays APIs.
If the link works then you can use it with fetch. Uploading json data to send to MongoDB as the case maybe.

My CRUD app works locally but not on Heroku

I've created a CRUD app and it works locally, but I can't get it to work fine on heroku. It deploys correctly, the website seems to work, but then I can't get the items I need from the database, as it keeps saying connection refused.
I added the .env variables to Heroku, as well as setting the port to process.env.PORT || 5000 and app.listen(port), I'm not sure what's causing the error. I also have a Procfile with web: node server.js, and a "start" script in package.json that points to server.js. It seems that the server doesn't start at all.
Here the repo in case you want to have a look https://github.com/ThomYorke7/inventory, here the app on heroku https://boardgamenerd.herokuapp.com/
The problem lies in the fact that your application has a backend (server) and a frontend (client) which are served differently locally than on Heroku.
I suppose locally your client is running on localhost:3000 (as it is the default with create-react-app you bootstrapped).
While your backend is running on localhost:5000, your client's package.json contains this line to make it work locally:
"proxy": "http://localhost:5000",
If I visit this page of your app: https://boardgamenerd.herokuapp.com/ > boardgames,
then I face these errors on the browser console:
boardgames-list.jsx:18
Error: Network Error
at e.exports (createError.js:16)
at XMLHttpRequest.p.onerror (xhr.js:83)
xhr.js:178
GET http://localhost:5000/boardgames/ net::ERR_CONNECTION_REFUSED
It tells you that your production version still calls backend on localhost:5000.
I.) First I'd try to fix these fetches by changing to relative URLs.
E.g. the above example (boardgames-list.jsx:18)
❌ your current script has hardcoded localhost fetch at the moment:
useEffect(() => {
axios
.get('http://localhost:5000/boardgames/')
.then((response) => {
setBoardgames(response.data);
setLoading(false);
})
.catch((err) => console.log(err));
}, []);
✔️ make it relative to root by removing "http://localhost:5000":
useEffect(() => {
axios
.get('/boardgames/')
.then((response) => {
setBoardgames(response.data);
setLoading(false);
})
.catch((err) => console.log(err));
}, []);
And it will work on Heroku. In case it wouldn't: see my suggestion below.
II.) Second, a suggestion:
Now your https://boardgamenerd.herokuapp.com/boardgames route uses the following backend endpoint to fetch data: https://boardgamenerd.herokuapp.com/boardgames/
The difference is only the last slash ("/") character which can be confusing and cause more issues later!
It is a best practice to add a differentiator path element to your backend endpoints, like /api/. For example: https://boardgamenerd.herokuapp.com/api/boardgames So you can be sure by first sight which GET request related to the backend and which one to the client.
If you'd go with this solution, you will need to add the following to your server.js:
app.use(express.static(path.join(__dirname, 'client', 'build')))
// required to serve SPA on heroku production without routing problems; it will skip only 'api' calls
if (process.env.NODE_ENV === 'production') {
app.get(/^((?!(api)).)*$/, (req, res) => {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'))
})
}
/^((?!(api)).)*$/ regex skips URLs containing "api" in their path, so they won't be served static as the client/build folder's content - api calls won't be served from static and will work fine.

Resources