I have a very simple Express server with a single route. I want to call this route with ajax from my html page and return json to the page.
The server side function gets called successfully but the failure method of the ajax method gets called the whole time. It never succeeds.
NodeJs
app.get('/test', function(req, res) {
console.log("TEST WAS CALLED");// This Logs to Console
res.json({ message: 'Hello World' });
});
Client Ajax
function FetchData(callbackfn) {
$.ajax({
type: "GET",
url: "http://localhost:3000/test",
async:false,
cache:false,
success: function (data) {
callbackfn(data)
},
error: function (textStatus, errorThrown) {
console.log(errorThrown);
console.log(textStatus);
callbackfn("Error getting the data")
}
});
}
function Callback(data) {
alert(data);
}
Related
I am trying to send my sql query results from node.js to my html. When I log it in the console it shows the correct data, but once I add it to the "res.send" in a stringified format and try to retrieve it with ajax in index.html the object I get doesn't have the data, just my entire HTML code.
I've tried changing my ajax to many different things I found online but nothing changes. I've tried changing POST to GET, changing the url (which just breaks it), only using success and not complete (which results in no object coming through).
node.js code excluding server code:
var sql = require('mssql/msnodesqlv8');
var config = {
connectionString: 'Driver=SQL Server;Server=NAME-PC\\SQLEXPRESS;Database=master;Trusted_Connection=true;'
};
sql.connect(config, err => {
new sql.Request().query('SELECT * FROM Companies', (err, result) => {
console.log("Works");
if(err) { // SQL error, but connection OK.
console.log(" Error: "+ err);
JSON.stringify(err);
} else { // All good.
console.dir(result);
JSON.stringify(result);
app.get('/', function data(req, res, next) {
res.send(JSON.stringify(result))
})
};
});
});
sql.on('error', err => { // Connection bad.
console.log("Bad");
console.log(" Error: "+ err);
});
HTML Ajax code:
<script>
jQuery.support.cors = true;
$.ajax({
type: "POST",
dataType: 'json',
url: '/',
contentType: "application/json; charset=utf-8",
complete: function(data) {
console.log(data);
},
success: function(data){
console.log(data);
}
});
</script>
The object I end up with has a responseText that has all of the HTML code. Any idea what I am doing wrong that the response isn't my data?
I want to make a request or api call on server 1, this server then automatically request to Server 2 and send the response back to server 1. I am using NodeJs and Express.
Example:
app.post('/api/Is', function(req, response, callback) {
})
I am calling that API in postmain as : http://localhost:3000//api/Is
So it should automatically go on http://localhost:5000//api/Is and send the response back to http://localhost:3000//api/Is call.
I should only call http://localhost:3000//api/Is and in backend code it will take request body and pass it to http://localhost:5000//api/Is and send the response back to http://localhost:3000//api/Is
I think you can consider use the the proxy lib like 'node-http-proxy', the most easy way.
otherwise, you must be transfer the request and response use 'http moudle', like this(no debug, not sure it will work perfectly~):
const http = require('http');
app.post('/api/Is', function(req, response, callback) {
const options = {
host:'localhost',
port:'5000',
path:'/api/Is',
method: 'POST'
// maybe need pass 'headers'?
};
let proxyBody = '';
const req2 = http.request(options, function(res2) {
res2.on('data',function(chunk){
proxyBody += chunk;
}).on('end', function(){
// here can feedback the result to client, like:
// const { headers } = res2;
// response.send(proxyBody)
});
});
// .on('error'){} here handle the error response
req2.end();
});
you need to use any library to make API call from server1 to server2. below code I am using fetch library.
To install the fetch library
npm install node-fetch --save
//SERVER1//
const fetch = require('node-fetch');
router.get("/api/Is", async (req, res) => {
try{
let {success, data} = await getDataFromServer2(req);
if(success) return res.send({success: true, data: data})
res.send({success: false})
}catch(e){
res.send({success: false})
}
});
function getDataFromServer2(req){
return fetch('http://localhost:5000//api/Is', {
method: 'post',
body: req,
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json())
.then((response)=>{
return {
success: true,
data: response
}
}).catch((error) => {
throw new Error("unable to fetch the roles ")
})
}
I'm using ajax to do so and am responding with res.end on the backend but so far, I can only POST once. Here is my code:
Server
app.post("/awesome", passwordless.restricted({ failureRedirect: "/" }), (req, res, next) => {
// ...do a bunch of stuff
res.end();
});
Client
$("[data-new-save]").on("click", function () {
$.ajax({
url: "/awesome",
type: "POST",
data: awesomeDetails,
success: function () {
console.log("Cool beans");
refreshContent(); // Re-renders content
// Feedback
$("nav").after("<div class=\"flash success\">Success!</div>");
setTimeout(function () {
$(".flash").remove();
}, 5000);
},
error: function () {
console.log("Welp");
// Feedback
$(".navigation").after("<div class=\"flash error\">Failure</div>");
setTimeout(function () {
$(".flash").remove();
}, 5000);
}
});
});
This sounds like a case for event-delegation. The best guess I have is that your refreshContent() function is removing the original [data-new-save] elements and creating new ones. This will cause the bound click event to be removed as well as it is a property of the DOM nodes that existed when it was originally called. You can get around this by delegating the event to a DOM node that does not get "refreshed", I'm assuming that the <body> tag does not get redrawn, only some set of children, so if you target <body> and look for selectors that match "[data-new-save]" it should function properly:
$('body').on('click', "[data-new-save]", function () {
$.ajax({
url: "/awesome",
type: "POST",
data: awesomeDetails,
success: function () {
console.log("Cool beans");
refreshContent(); // Re-renders content
// Feedback
$("nav").after("<div class=\"flash success\">Success!</div>");
setTimeout(function () {
$(".flash").remove();
}, 5000);
},
error: function () {
console.log("Welp");
// Feedback
$(".navigation").after("<div class=\"flash error\">Failure</div>");
setTimeout(function () {
$(".flash").remove();
}, 5000);
}
});
});
This is what i used for something similar:
$(document).ready(function () {
$('#myform').on('submit', function(e) {
e.preventDefault();
$.ajax({
url : $(this).attr('action') || window.location.pathname,
type: "GET",
data: $(this).serialize(),
success: function (data) {
$("#form_output").html(data);
},
error: function (jXHR, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
});
I'm using proxy.web to forward client requests.
When destination server is up, my code works as expected.
When destination server is down, ECONNREFUSED error is catch and printed to console.log. I would like to send that error back to the client, and tried using the sample provided here. Unfortunately, the error response does not arrive to the client (tried both chrome and firefox). Please find below code. Why does the response not sent to the client ?
var proxyServer = http.createServer(function(req, res) {
if(req.path === 'forbidden') {
return res.end('nope');
}
var url_parts = url.parse(req.url);
var extname = path.extname(url_parts.pathname);
if (extname || url_parts.pathname.length <= 1){
proxy.web(req, res, {
target: 'http://localhost:'+config.fileServer.port
});
}
else{
proxy.web(req, res, {
target: config.recognitionServer.url
}, function(e) {
console.log(e.message);
if (!res.headersSent) {
res.writeHead(500, { 'content-type': 'application/json' });
}
res.end(JSON.stringify({ error: 'proxy_error',
reason: e.message
}));
});
}
}).listen(config.proxyServer.port, function () {
console.log('Proxy server is listening on port '
+ config.proxyServer.port);
});
A good approach is this:
return res.status(500).send({
error: true,
message: 'your-error-message'
});
Your code rewritten:
proxy.web(req, res, {
target: config.recognitionServer.url
}, function (e) {
console.log(e.message);
return res.status(500).send({
error: true,
message: e.message
});
});
Problem was solved on client side :)
Client code is JS using XMLHttpRequest (tested on FF and Chrome). The error response arrives to "onload" event handler, not to "onerror".
The "onload" handler function needs to check response status. If error status (500), continue with error handler.
I want to make a jquery ajax post inside my azure mobile services api get method. that is, something like I have below. That is, I want the GET method to return data that returns something from ithe result of my ajax POST.
It's not obvious how I would do that.
exports.get = function(request, response) {
$.ajax({
type: "POST",
url: url,
data: data,
success: function(x) { return MYLIST },
dataType: dataType
});
response.send(statusCodes.OK, { message : 'Hello World!' });
};
UPDATE:
Per Carlos Post : http://blogs.msdn.com/b/carlosfigueira/archive/2013/12/12/expanded-login-scopes-in-azure-mobile-services.aspx I now understand that the exports.get code should be in the API section of the azure mobile service. When I put that code into that section I get an Internal Error, 500 in my failure event of the jquery call. my alert does show I successfully logged into google.
var client = new WindowsAzure.MobileServiceClient('https://svcc.azure-mobile.net/', val);
$(document).ready(function () {
$("#submit1").click(function () {
client.login("google").done(function (results) {
alert("You are now logged in as google: " + results.userId);
$.ajax({
url: "http://xxxxx.azure-mobile.net/api/test1",
success: function (data, textStatus) {
debugger;
//data - response from server
},
error: function (jqXHR, textStatus, errorThrown) {
debugger;
}
});
}, function (err) {
alert("Error: " + err);
});
});
You should use some node.js module which allows you to make HTTP requests. The simplest one is the 'request' module, which you can require on a server script and use it to make requests. For example, this code should do what you want:
exports.get = function(request, response) {
var req = require('request');
req({
url: url,
method: 'POST',
body: JSON.stringify({ theBody: [ 'hello', 'world' ]}),
headers: { "Content-Type": "application/json" }
}, function(err, result) {
response.send(statusCodes.OK, result);
}
}