Using AJAX request to get data from Node JS server [duplicate] - node.js

This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 4 years ago.
I am trying to get data from the back end Node server from the front end using a POST request but the HTML doesn't seem to catch and display the data properly. I've tested the backend using Postmaster and the data comes out fine. Can anyone help me out here? As the project complete code is kinda huge, I'll add the relevant snippet for now.
Backend is node.js:
#!/usr/bin/env node
app.post('/data', urlencodedParser, function(req, res) {
//config = DB auth data
var pool = new pg.Pool(config);
pool.query('SELECT url FROM imgs WHERE uid=$1 OR uid=0', [usid], function(err, result) {
if (err) {
console.log(err);
res.status(400).send(err);
}
imgs = JSON.stringify(result.rows);
res.send(imgs);
});
// Rest of the code ...
}
});
<html>
<body>
<button type="button" onclick="server()">submit</button>
<p id="demo"></p>
<script>
function server() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("POST", "http://localhost:8000/data", true);
xhttp.send();
}
</script>
</body>
</html>
UPDATE : Turns out I need CORS to make this work. Thanks everyone for helping me out and #Quentin for finding what I was missing.

Try using Jquery,
In your backend, your xhttp request can be replaced as below :
function server() {
var body = {"name":"Bob"}; //whatever data you want to pass to the post request
$.ajax({
type: "POST",
url: 'http://localhost:8000/data',
data: JSON.stringify(body),
success: function(result) {
console.log(result);
},
contentType: 'application/json'
});
}

Related

express force refresh client webpage

Im trying to refresh a clients webpage (using a router) and everywhere I look I see something along the lines of using res.redirect(same page link of some sort), however for some reason this isnt working for me, do you know of any alternatives?
my code looks something like this
router.post('/sendSnippet', function (req, res) {
req.on('data', function(data) {
User.findOne({email: req.user.email}).then((userToEdit) =>{
if(userToEdit){
var newSnippet = {
"types":[],
"code": data.toString()
}
userToEdit.snippets.push(newSnippet)
userToEdit.save().then(()=>{
//refresh here
res.redirect('/profile/');
})
}
})
})
});
thanks for any help in advance
Assuming you are trying to force-reload a client's browser tab for your website, I don't think you can do that server-side.
You can use meta http-equiv or the Refresh HTTP header to tell the client's browser to refresh the page after some time or use client javascript to refresh the page:
Router:
router.post("/example", (req, res) => {
res.header("Refresh", "10"); // tells the browser to refresh the page after 10 seconds
res.send("your data");
});
Meta:
<head>
<!-- Refresh after 10 seconds -->
<meta http-equiv="refresh" content="10">
</head>
Javascript + html:
<html>
<body>
<script>
// reloads after 10 seconds
setTimeout(() => {
location.reload();
}, 10000);
// or you could have some kind of API to tell when to refresh the page
function check() {
const x = new XMLHttpRequest();
x.open("GET", "some path");
x.send();
x.onload = function() {
if (x.response === "done") {
location.reload();
} else {
setTimeout(check, 1000);
}
}
}
check();
</script>
</body>
</html>

How can I call an AJAX funtion from server side in Express/Node JS?

Following is my POST function in Node js. I want to call a funtion in my client side HTML to display an error message on the page.
router.post('/',(req,res)=>{
const data = JSON.stringify({
institute_name: req.body.institute_name,
email : req.body.email,
password : req.body.password
})
const options = {
host:'localhost',
port:'8888',
path:'/registerInstitute',
method:'POST',
headers: {
'Content-Type':'application/json'
}
}
const req1 = http.request(options, (res1)=>
{
const status = res1.statusCode
if (status == 201)
{
//admin created
res.redirect('/?account_created=true')
}
else if ( status == 409)
{
//CALL AJAX FUNCTION TO DISPLAY ERROR MSG
}
})
req1.write(data)
req1.end()
})
The simple answer is NO. But there are workarounds to do so and I've demonstrated the one that will suite your scenario
Sockets
You can use web sockets to trigger event to notify client to run specific function
On service side you can do something like this:
var io = require('socket.io').listen(80); // initiate socket.io server
if (
io.sockets.on('connection', function (socket) {
if ( error == 403 ) {
socket.emit('runErrorFunction', { error: "error data" });
}
});
You can do something like this on client side:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost'); // connect to server
socket.on('runErrorFunction', function (data) { // listen to runErrorFunction event raised by the server
// Here goes your error showing logic
});
</script>
Here is the link for more info Socket.io

Nodejs is not receiving any code from Flask app.

I am really new in node js and a little bit more experienced in flaks. I am trying to connect a nodejs backend with a flask api. Basically I am sending a file that was uploaded in the nodejs app for processing (converting to another format) to my flask app.
For sending the data I am using request. In this way:
app.post('/converttest', uploader.single('file'), function(req,res){
var file = req.file,
result = {
error: 0,
uploaded: []
};
flow.exec(
function() { // Read temp File
fs.readFile(file.path, this);
},
function(err, data) { // Upload file to S3
var formData = {
file: data,
};
requestPack.post({url:'http://127.0.0.1:5000/api/resource/converter', formData: formData});
},
function(err, httpResponse, body) { //Upload Callback
if (err) {
return console.error('upload failed:', err);
}
res.redirect('/console');
});
});
Then I am receiving the file for processing in the flask app, like:
#app.route('/api/resource/converter', methods = ['POST','GET'])
def converter_csv():
if request.method == 'POST':
f = request.form['file']
if not f:
abort(400)
print('-----Converting-------')
file = open("temp/converting.txt","w")
file.write(f)
#....conversion process...
# Finish the process
return Response(converted_file,status=200)
In my console for the localhost of the flask app, I am getting:
127.0.0.1 - - [09/Aug/2017 15:47:59] "POST /api/resource/converter HTTP/1.1" 200 -
However my nodejs app did not receive any response. It just got frozen.
I appreciate any orientation anyone can give me. Thanks.
I think flow.exec is not in proper order
router.post('/converttest', uploader.single('file'), function(req, res) {
var filePath = req.file.path;
fs.readFile(filePath, 'utf8', function(err, data) { //change format reading as required
try {
formData = {file:data}
requestPack.post({url:'http://127.0.0.1:5000/api/resource/converter', formData: formData});
} catch(err) {
return console.error('upload failed:', err);
res.redirect('/console')
}
fs.unlink(filePath);}); });
I ended up using requestify. Seems like they make it a little bit easier for beginners like me:
var requestify = require('requestify');
app.get('/convertupload', function(req,res){
res.render('pages/convertupload');
});
app.post('/converttest', uploader.single('file'), function(req,res){
var file = req.file,
result = {
error: 0,
uploaded: []
};
flow.exec(
function() { // Read temp File
fs.readFile(file.path,this);
},
function(err, data) { // Upload file to S3
var formData = {
file: data
};
requestify.post('http://127.0.0.1:5000/api/resource/converter', {
form: formData
})
.then(function(response) {
// Get the response body (JSON parsed or jQuery object for XMLs)
console.log(response)
response.getBody();
});
res.redirect('/login');
});
});

Stop multiple async calls from client Node JS Angular

I have a single page app that gets a list of objects from an node js server. However if the user selects the first item in the list before the rest of the related objects are loaded it needs to cancel the request. I can cancel the request on the client side (angular) but don't see how to cancel a request on an already started call in node !
The code below is the method i use to call the node api with the ability to cancel that request on the client side.
getDiscovery : function(ids) {
var Ids = [],
apiUrl = '/api/Something/ids',
self = this,
deferredAbort = $q.defer();
// Initiate the AJAX request.
var request = $http({
method: "get",
url: apiUrl,
params: {
ids: JSON.stringify(ids)
},
timeout: deferredAbort.promise
});
var promise = request.then(
function(response) {
return(response.data);
},
function(response) {
return($q.reject( "Something went wrong" ));
}
);
promise.abort = function() {
deferredAbort.resolve();
};
promise.finally(
function() {
console.info( "Cleaning up object references." );
promise.abort = angular.noop;
deferredAbort = request = promise = null;
}
);
return(promise);
}
This is the method on the node api which needs to be cancelled
exports.getItemsDiscovery = function(req, res){
var Items = JSON.parse(req.query.ids);
async.each(Items,
function(Item, callback){
method.getSomething(Item.Id, function(data){
console.log('Got data for', item.Id);
callback();
});
},
function(err) {
return res.send(Items);
});
};
The route is
app.get('/api/ids', something.getItemsDiscovery);
Any help would be much appreciated
Rob

Node.js request web page

I need to connect to a web page and return the status code of the page, which I've been able to achieve using http.request however the pages I need to request can take a long time, sometimes several minutes, so I'm always getting a socket hang up error.
I'm using the following code so far:
var reqPage = function(urlString, cb) {
// Resolve the URL
var path = url.parse(urlString);
var req = http.request({
host: path.hostname,
path: path.pathname,
port: 80,
method: 'GET'
});
req.on('end', function() {
cb.call(this, res);
});
req.on('error', function(e) {
winston.error(e.message);
});
};
What do I need to do to ensure that my application still attempts to connect to the page even if it's going to take a few minutes?
Use the request module and set the timeout option to an appropriate value (in milliseconds)
var request = require('request')
var url = 'http://www.google.com' // input your url here
// use a timeout value of 10 seconds
var timeoutInMilliseconds = 10*1000
var opts = {
url: url,
timeout: timeoutInMilliseconds
}
request(opts, function (err, res, body) {
if (err) {
console.dir(err)
return
}
var statusCode = res.statusCode
console.log('status code: ' + statusCode)
})
Add this if you don't want to use a higher level http client like request or superagent , then add this...
req.on("connection", function(socket){
socket.setTimeout((1000*60*5)); //5 mins
});

Resources