Im trying to send a POST request from my React application. The application is running locally in node on localhost:8000.
I've tried running in locally on localhost:5000 and also pushed the server application to a heroku webaddress and tried sending to that address.
So basically my question is;
1. how do I send a POST request to my heroku server when i'm running my react application locally on localhost?
2. How do I receive this POST request on my heroku server/node application?
React code for sending POST request:
import React, { Component } from 'react'
import axios from 'axios'
require('styles/_webshopPage/webshop.css')
export default class Checkout extends Component {
postRequest() {
let nodeServerURL = 'https://peaceful-mountain-93404.herokuapp.com'
let reqData = {
msg: 'hello!',
}
// Send a POST request
axios({
method: 'post',
url: nodeServerURL,
data: reqData
})
}
render() {
return (
<div >
<button onClick={this.postRequest.bind(this)} type="button" name="button">Send req</button>
</div>
)
}
}
Code for my heroku server:
var express = require('express')
var app = express()
app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))
app.post('/', function(request, response) {
response.send('Hello World!')
})
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
I have done something similiar like that..
I think Fetch api works perfectly with it .
Fetch provides a generic definition of Request and Response objects (and other things involved with network requests). This will allow them to be used wherever they are needed in the future, whether it’s for service workers, Cache API and other similar things that handle or modify requests and responses, or any kind of use case that might require you to generate your own responses programmatically.
I have typing some random example here, hope it will you to understand how fetch api exactly works
var data= "somerandom string";
fetch('http://localhost/react_task/form_send.php', {
method: 'post',
body: JSON.stringify({
Password: data,// this is posted on another server
})
}).then(function (res) {
return res.text();
}).then((body)=> {
console.log(body)// body can be used to get data from another server
});
i think fetch helps perfectly lot for posting and getting data from another server..
Enjoy Coding.
Related
Backend code example: I am trying to get users here from my SQL Server database Account:
async function executeQuery() {
try {
const pool = await sql.connect(config);
const result = await pool
.request()
.query(`USE Account SELECT TOP 10 UserNo FROM UserTable`);
return result;
} catch (err) {
console.log(err);
}
}
app.get("/api/data", async (req, res) => {
const result = await executeQuery();
res.json(result);
});
React frontend code: I am getting an error when try to render data from SQL Server.
import React, { useState, useEffect } from "react";
function SqlTest() {
const [data, setData] = useState([]);
async function fetchData() {
const result = await fetch("/api/data").then((res) => res.json());
setData(result);
}
useEffect(() => {
fetchData();
}, []);
return (
<div>
{data.map((item) => (
<div key={item.UserNo}>{item.UserNo}</div>
))}
</div>
);
}
export default SqlTest;
I am trying to render data from SQL Server, but nothing helps..
Ok, your problem is a very common one that has a very common solution.
You have 2 separate projects (HTTP servers):
The HTTP server that CRA comes with, which is a NodeJS server.
Your API server, which happens to also be a NodeJS server.
Now you want to fetch data from React by querying your API server.
Look at your URL: api/data. This is a relative URL. Relative URL's are resolved by the browser by using the current page's domain. I don't know your exact setup, but the URL will end up being something like http://localhost:3000/api/data.
Do you see the problem already? Your API server is not listening on port 3000. It is probably listening on some other port number. After all, no 2 applications can listen on the same TCP port.
So you would then be tempted to change your fetch URL to a full URL that specifies the server API: http://localhost:3001/api/data. That probably works, but there's a chance it errors out due to CORS.
So long story short, do as the CRA help pages say you should do: Set a proxy up in your CRA server. Here it is: https://create-react-app.dev/docs/proxying-api-requests-in-development/
In a nutshell, create the file src/setupProxy.js with code similar to this:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000', // <-- USE YOUR API PORT
changeOrigin: true,
})
);
};
The sample assumes you're running your API server in port 5000. Change it to fit your configuration.
I have been working on a NodeJS express app that uses EJS and node-fetch to fetch my Api from my vps server, but it won't get fetched, every page of the app will load but the page that uses the Api where I am fetching the Api won't work, I have been trying to solve this issue for almost a week now but cannot get anywhere
My App.js
const express = require('express');
//node fetch used here is a fork of the original and i have tried both original and this
//both have the same result
const fetch = require('#formio/node-fetch-http-proxy');
const port = 3000;
...
...
... <- some code here
...
...
app.get('/', (req, res) => {
res.render('index');
});
app.get('/xyz',(req,res) => {
var url = 'http://XX.XX.XX.XX:8080/api';
try {
fetch(url, {
method: 'GET',
headers: {
'api-key': process.env.API_KEY,
'Content-Type': 'application/json'
}
}).then((resp) => {
return resp.json();
}).then((data) => {
...
... <- some code here
...
res.render('xyz',{categories: categories , ...});
}).catch((err) => {
console.log(err);
});
}
catch(err) {
console.log(err);
}
});
...
... <- some code here
...
Error I am getting :-
With both Axios and node-fetch I have been getting a common error of
connect ECONNREFUSED XX.XX.XX.XX:8080
Some of the things that I have tried :-
I have switched from Axios to node fetch thought maybe that had to do something with it, I have hosted a new node app on vps that when requested will show a msg in console that a request was made and pass the Json by locally fetching it, when I made a request from postman it worked the console logged 'Request was made' but when I tried it on the cPanel hosted app it did not show anything, I have also tried making my Api a https response but that did not work ether.
Note :-
The app is working fine when i host it in local pc, when i host the node app in cPanel it won't work.
Solution Found :-
because I am new to web developing and never used cPanel before, I had to allow my backend vps server Ip after contacting my web server provider he allowed the Ip and now it's working like a charm
I'm trying to get information with a fetch (client) and a get (server) requests to get data from the server with the client and printing it.
for some reason I can't get the information I'm looking for and I think it has somthing to do with the url I'm entering, can I get an explanation, or maybe an example about the url I'm supposed to enter?
I'll enter my code as an example:
client:
//bitcoin page: url - 'http://localhost:3000/bitcoin'
//NOTE: the proxy is: 'http://localhost:3001'
import React from "react";
import { Link } from "react-router-dom";
function BitCoin() {
const [data, setData] = React.useState(null);
console.log("entered bitcoin page");
React.useEffect(() => {
fetch("NOT SURE WHAT TO WRITE HERE")
.then((res) => res.json())
.then((data) => setData(data.message));
}, []);
return (
<div style={{textAlign:"center", fontFamily:"Comic Sans MC", fontSize:"100"}}>
THIS IS THE BitCoin PAGE
<nav>
<Link to="/"> Home </Link>
</nav>
<nav>
<Link to="/coins"> Coins </Link>
</nav>
<p>{!data ? "Loading..." : data}</p>
</div>
)
}
export default BitCoin;
server:
//index.js: url - 'http://localhost:3001'
const express = require("express");
const PORT = process.env.PORT || 3001;
const app = express();
app.get('NOT SURE WHAT TO WRITE HERE', (req, res) => {
console.log("entered bitcoin query!");
let msg = "";
//some functions to get the msg I'm looking for (not relevant)
res.json({ message: msg });
});
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
as you can see there's a log when entering the get request but the console's not logging it, I'm guessing the client and the server are not communicating and that's what makes the problem.
thank you <3
It's important to understand the general architecture of your technology stack:
You have the React frontend running under http://localhost:3000. This is simply serving the React app through a development server on your computer.
Additionally, you have a NodeJS app (using express) running at http://localhost:3001. Notably, this runs under a different port to the React app.
In your express code, you would define a url which the React frontend can call, to fetch data. So let's call it /coin-message:
app.get('/coin-message', (req, res) => {
Now, in the React app, you can make ajax requests to this url:
fetch("http://localhost:3001/coin-message")
Note that you need to include the full URL and port in the fetch() - this is because the Node app runs under a different port.
Important
Because you want to make ajax requests to a URL which has a different port to the React app, you will encounter a Same Origin Policy problem. This is a security measure activated by browsers to prevent web app vulnerabilities. To solve this, you can use one of the CORS middlewares for express, such as this one.
server:
app.get('/bitcoin', ...)
client:
fetch('http://localhost:3001/bitcoin')
Before going to question, please note, I have tried many suggestions from stackoverflow as well as many other websites. There are many suggestions, but most of them truly dont solve this question straight.
My question in simple one sentence is, how to let my web server (which is a node js express based api) know, the logged windows user id (from my react js application) in an intranet application?
Till now I am able to write express based node js server which uses node-sspi library and provides me the windows user id and groups.
This API is as simple as
var express = require('express');
var app = express();
var server = require('http').createServer(app);
let cors = require('cors')
app.use(cors())
app.use(function (req, res, next) {
var nodeSSPI = require('node-sspi');
var nodeSSPIObj = new nodeSSPI({
retrieveGroups: true
});
nodeSSPIObj.authenticate(req, res, function(err){
res.finished || next();
});
});
app.get('*', function (req, res, next) {
res.json({msg: '************ Server reply by user ' + req.connection.user})
});
// Start server
var port = process.env.PORT || 3002;
server.listen(port, function () {
console.log('Express server listening on port %d in %s mode', port, app.get('env'));
});
React App.js code is
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
msg: "Not known",
localdata:"local status",
status:"not set",
};
}
componentDidMount()
{
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json',
},
})
.then(response =>
{
this.state.status = response.status;
return response.text();
}
)
.then(msg =>
this.setState({ msg })
);
}
render() {
return (
<div className="App">
<div> LocalData is - {this.state.localdata}</div>
<div> Server data is - {this.state.msg} </div>
api call status is - { this.state.status }
</div>
);
}
}
export default App;
In the above code, If you do API call from browser you get correct reply
http://192.168.7.179:3002/
{"msg":"************ Server reply by user IUYT\\user1"}
But, from react app
LocalData is - local status
Server data is -
api call status is - 401
in F12 window
Failed to load resource: the server responded with a status of 401 (Unauthorized)
Please suggest changes required for calling from react app.
After researching finally got a breakthrough yesterday. So thought to answer my own question.
5 points to change in my example.
We need to refer both client and server with IP addresses or domains
for communication purposes. So I changed all api calls origin
mentions to their respective IP addresses.(localhost -> 192...)
In cors, we need to mention IP address and port number as origin
In client side calls if we are using fetch use credentials: include or if axios use withCredentials: true
In server, cors must know the origin, so include your clients ip with port
Use either express-ntlm or node-sspi as your windows authenticator.
So Total change to my code in the example is,
In server side
var corsOptions = {
origin: 'http://192.168.7.179:3001',
credentials: true,
authenticate: true,
authorization: true,
optionsSuccessStatus: 200
}
app.use(cors(corsOptions))
instead of
app.use(cors())
and in client side add 'credentials: 'include'' as parameter to fetch.
change
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json',
}
})
to
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
credentials: 'include'
})
Thats it, first run api then launch when you launch your react app and you will get a prompt for windows auth.
Fill in your domain credentials and server will fetch results.
Steps
1. In browser see if server is running -> http://192.168.7.179:3002/
{"msg":"************ Server reply by user IUYT\user1"}
Check in http://localhost:3001/ result is
LocalData is - local status
Server data is - Not known
api call status is - not set
BUT
In browser see if client is running -> http://192.168.7.179:3001/
LocalData is - local status
Server data is - {"msg":"************ Server reply by user IUYT\user1"}
api call status is - 200
I'm trying to make a GET request to a URL and getting an image from there as a response using node and express.
This is my code:
var app = require('express')();
var http = require('http').Server(app);
app.get('http://tapas.clarin.com', (req, res) => {
res.sendFile('index.html');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
The view is showing a Cannot GET /.
How can I make this request work properly to show the recieved image in my view ?
HTML
<div id="tapas">
// I want to show the image from the response here!
</div>
<script src="./app.js"></script>
</body>
app.get() is used to create a GET API on your server. What you need is a package that can help you to make API calls to other servers and fetch data from there.
You could use the request-promise npm package to make life easier for you.
var rp = require('request-promise');
var options = {
uri: 'https://api.github.com/user/repos',
qs: {
access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
},
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function (repos) {
console.log('User has %d repos', repos.length);
})
.catch(function (err) {
// API call failed...
});
EDIT: After re-reading your question, you don't really need to do a GET API call and fetch the image on your server before showing it on your website. You could directly pass the URL to your img tag like this -
<img src="https://url/image.png" alt="example">