Creating a simple Node.js web service for use with AJAX - javascript

I have a basic Node.js http server set up as per the docs, I'm trying to create a very simple web service I can talk to with Javascript (AJAX) which I'll then hook up to Arduino. It's a test piece, I may go down the road of something else but this is proving to be fun. Anyway, here is the server-side javascript:
var http = require('http');
var _return = 'Bing Bong';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'application/jsonp'});
//do stuff
res.end('_return(\'Hello :-)\' + _return)');
}).listen(process.env.VMC_APP_PORT || 1337, null);
And this is the client side:
function experimentFive(node) {
console.log('X5 Func started');
console.log('Calling Node.js service');
var nodeURL = node;
$.ajax({
url: nodeURL,
dataType: "jsonp",
jsonpCallback: "_return",
cache: false,
timeout: 50000,
success: function(data) {
console.log('Data is: ' + data);
$("#nodeString").text(" ");
$("#nodeString").append(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('error : ' + textStatus + " " + errorThrown);
}
});
}
experimentFive('http://fingerpuk.eu01.aws.af.cm/');
This works, I get the data back but not as I'd expect. What I'd like to be able to do is change some data server side and receive that back. I get back the string in the res.end plus:
function () {
responseContainer = arguments;
}
Instead of the variable's data. No matter how I try to get that data back, it is either undefined or this response.
From research I think the variable is not having it's data set before the callback fires, so it's empty. But if I set an initial value the data is still undefined.
Am I missing something very simple here? Should I just go back to C#?
Cheers.

One possible way of accomplishing this would be to use ExpressJS with NodeJS to handle routing your endpoints. By doing this you can set up routes such as GET /media/movies/, fire an AJAX request to this route, then have it return JSON data that you can handle on your app.
Here's an example of ExpressJS routing in an app that I made:
var groups = require('../app/controllers/groups');
// find a group by email
app.post('/groups/find', groups.searchGroupsByEmail);
Here is a great tutorial that I used when getting started with Express. It walks through the entire process from installing Node.JS (which you've already done) to setting up the ExpressJS routing to handle incoming HTTP requests.
Creating a REST API using Node.js, Express, and MongoDB

Related

ajax get to 3rd party server within express middleware results in 500 error

I have a requirement to access multiple devices over IP from an HTML5 web app.
My approach to working around the cross-domain impossibility of doing this all on the client side has been to "cook" requests from the client inside of express' middleware. A route receives a get or post from the client, and then performs a get or post to the 3rd party device identified by the payload from the client.
I'm using the code to get info from a device. It works just fine when I run it directly from file inside of a client I made for testing purposes. Running directly from file avoids the CORS difficulty because the client is also the server I guess.
When I run the same code from within an express route, I get a 500 error.
Am I trying to do something impossible? I'm only about a week into node, express etc so hopefully it's something dumb and easy to solve. I'm taking fact that I haven't been able to find any other questions quite like this as an indication that there's a proper way to achieve what I need.
// post to find a camera
router.post('/find', function(req, res) {
var url = 'http://' + req.body.addr + '/cgi-bin/aw_cam?cmd=QID&res=1';
console.log(url);
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function (result) {
console.log('success: ' + result);
res.send(result);
},
error: function (xhr, textStatus, err) {
console.log('error: ' + textStatus);
}
});
});
Here's what logged to the server console:
http://192.168.0.10/cgi-bin/aw_cam?cmd=QID&res=1
POST /cameras/find 500 126.593 ms - 1656
Thanks in advance!
ok I found how to do this. The trick is to use Node's built-in http messaging capabilities. I found a good article on how to do this here
The code below does exactly what I wanted from within my custom route middleware. I guess I just learned that I can only use AJAX how I wanted on the client side.
This lets me abstract the hairier details of the device control protocol into the server, leaving my client apps to use JSON/AJAX model to interact with them. Success!
var http = require('http');
// post to find a camera
router.post('/find', function(req, res) {
var url = 'http://' + req.body.addr + '/cgi-bin/aw_cam?cmd=QID&res=1';
console.log(url);
http.get(url, (response) => {
console.log(`Got response: ${response.statusCode}`);
var body = '';
response.on ('data', function(d) {
body += d;
});
response.on ('end', function () {
console.log('received: ' + body);
var reply = {};
if (body.indexOf('OID:') == 0) {
reply.msg = body.slice(4);
reply.ok = true;
} else {
reply.msg = body;
reply.ok = false;
}
res.send(reply);
});
// consume response body
response.resume();
}).on('error', (e) => {
console.log(`Got error: ${e.message}`);
});
});

sock.js not allowing POST method for node server

Trying to bring up a node server that uses sock.js for websocket communication.
Can bring up the server fine and have established the websocket communication. However, we also need to POST to this instance with HTTP so that we can then send a message through the websocket. The message is dependent on the POST payload...
However, sock.js does not seem to be accepting the handler that we're creating, and is only allowing a GET method. This is causing a 405 HTTP code for any POSTs done to the server.
Please see following code. If I remove the sock.js implementation, I'm then able to process GET and POST requests with the server.
var app = require('http');
var sockjs = require('sockjs');
var sk = sockjs.createServer({ sockjs_url: '//cdn.jsdelivr.net/sockjs/1.0.1/sockjs.min.js' });
sk.on('connection', function (conn) {
console.log('connection' + conn);
conn.on('close', function () {
console.log('close ' + conn);
});
conn.on('data', function (message) {
console.log('message ' + conn,
message);
conn.write(message);
});
});
var server = app.createServer( function(req, res) {
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
req.on('end', function () {
console.log("Body: " + body);
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('post received');
}
else
{
console.log("GET");
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('get received');
}
});
sk.installHandlers(server);
I've tried different ways to set up the handlers, including following the example here; but regardless it just doesn't seem like I'm falling into my handlers but instead sock.js is not allowing POSTs.
If this is expected behavior from sock.js and is working the way it;s intended to, then recommendations for what to use would be appreciated. This is an attempt to move away from socket.io because that isn't working in all cases for us... but without being able to POST to the node server we probably won't be able to use sock.js either.
You're missing the prefix in your call to installHandlers. This results in sockjs handling all requests, rather than just those that are destined to it.
Just specify a prefix:
sk.installHandler(server,{prefix:"/whatever"});
It should of course match the prefix you use client-side.
Alternatively, if you don't want to use a prefix, use different ports.

Json returns undefined in nodeJs and AngularJs

I've got an app which makes calls to an api and shows data about that info: first, it takes a username from an input in the client and posts it to the server. In this step if I check if the data has been sent alright to the server everything seems fine.
AngularJs part:
var app=angular.module("app",[])
app.controller("InfoController",['$scope','$log','$http','$filter',function($scope,$log,$http,$filter){
$scope.info = {
summonerName: '',
};
$scope.info.onClick = function(){
$scope.info.summonerName = $scope.info.summonerNameBox;
$http.post('/api/getSummonerName', $scope.info);
$http.get('/api/summonerData')
.success(function(data, status){
$scope.info.display = data;
}).error(function(data,status){
alert("Error: " + status);
});
};
}])
Nodejs:
var summonerName;
var summonerId = '';
app.post('/api/getSummonerName', function (req, res){
summonerName = req.body.summonerName;
console.log("Post getSummonerName " + summonerName);
});
app.get('/api/summonerData', function(req,res){
LolApi.Summoner.getByName(summonerName, function(err, summoner) {
if(!err) {
res.json(summoner);
summonerId = req.body.summoner;
console.log(summonerId);
if(err)
res.send(err)
}
})
});
When I have this data in the server, I make a call to an api for getting this user's info, and everything goes fine as well.
The problem comes when I want to store an specific field from this json. When I want to store it in a variable, everything I get is "undefined" :/ (Once I achieved getting "[Object object]", but can't get it anymore...)
Any idea?
Thank you all.
In my opinion, this isn't the way you should do it.
If you want to do a get on a summoner, you need to just use the get method.
Especially if you're dealing with multiple users.
You might want to pass data in the get request like specified in this answer and ditch the post request:
AngularJS passing data to $http.get request
That way, you're not dependent on the memory and you're able to modularize it :)

How to get response from node-xmpp request?

I learned to make request with the XMPPserver by using node-xmpp library. Now i can make the request as mentioned in XMPP extensions documentations. But now i want to get the callback response for the each request (especially the XML response).
Here i have used the following code the make a request subscription (friend request) to a another user
var net = require("net");
var xmpp = require('node-xmpp');
var cl = new xmpp.Client({ jid: "one#localhost", password: "comet123$" })
cl.addListener('online', function(data) {
console.log('Connected as ' + data.jid.user + '#' + data.jid.domain + '/' + data.jid.resource)
//making subscription
var stanza = new xmpp.Element('presence',{
to: "hai#localhost",
from: "one#localhost",
type: "subscribe",
}).up
// making request
cl.send(stanza);
// nodejs has nothing left to do and will exit
cl.end()
})
I want to know, how to get the response result.
I tried with the callback functionality with as llike this,
cl.send(stanza, function(result){
console.log(result);
});
and also like this
var result = cl.send(stanza);
This returns only true,
So can anyone please tell me how do I get the callback result for the requests that we make by using the node-xmpp libarary
There is no callback or return for XMPP messages. You will have to have to set up an event listener to pick up messages coming back from the server. Add:
cl.on('stanza', function(stanza){
// Do something with the stanza
// If you want to end after the first message you get back, move this here
cl.end();
});
you can get raw data from connection
cl.connection.on("data", function (data) {
console.log('data', data.toString('utf8'));
});

JSONP call with server-side language as Javascript

I've been trying to use JSONP to get a JSON object from a server via a client-side call (on a different port). However, because my server is implemented in javascript using Node.js and Express, I haven't been able to find much on JSONP with Javascript on the server as most sites I found used php for server-side code.
I believe the issue is with how I set up the url with respect to the callback, which I'm a bit fuzzy on cause it's new to me.
On the server:
//Setting up server stuff
var express = require('express'),
app = express.createServer();
app.use(express.logger());
//Making a connection to the mongoDB to get the data that I want to display in the JSON object
new Db('prism',
new Server("127.0.0.1", 27017, {auto_reconnect: false}), {}).open(function(err, db) {
app.get('/getData', function(req, res) {
console.log('JSONPCALLBACK CALLED WITH RETURNDATA PASSED IN; SERVER SIDE');
if (typeof callback == 'function') {
console.log('callback is defined');
callback(returnData);
}
else {
console.log('callback is not defined');
}
}
});
And on the client:
$.ajaxSetup({ cache : false });
$.getJSON('http://127.0.0.1:1337/getData&callback=?', function(rtndata) {
console.log('SUCCESS');
console.log(rtndata);
});
embedded by the standard tags.
But I get the error:
GET http://127.0.0.1:1337/getData&callback=jQuery16108897686484269798_1311007334273?_=1311007334342 404 (Not Found)
The server is on port 1337 while the client is run through MAMP on localhost:8888. I'm not sure if its even a localhost related issue as I've been trying to get this setup running for a few days now.
I believe the issue has something to do with not writing this line, which is in php, into my server-side Javascript. Most of the JSONP examples I found had something like this. But I'm not sure.
if ($GET['callback'] != '')
$json = $GET['callback']."( $json )";
return $json;
Any help would be greatly appreciated. I apologize ahead of times for being super verbose.
Bests,
Cong
I think you have two problems. First is the 404. Completely separate from getting the client-side jQuery code to work, you need to make sure that you can issue a regular browser request (i.e. paste in that URL) and get back what you expect. I haven't used express, so it's hard for me to comment on why you'd be getting that, except to say that I don't see 1337 anywhere in your server-side code, just what appears to be the port number 27017.
The second problem is that you don't actually want to execute the callback on the server, just build the JSON response including the callback (string) prefixed to it.
So instead of this ...
if (typeof callback == 'function') {
console.log('callback is defined');
callback(returnData);
}
else {
console.log('callback is not defined');
}
try this:
if (callback) {
console.log('callback is defined');
res.write(callback + '(' + JSON.stringify(returnData) + ')');
}
else {
console.log('callback is not defined');
}
Hope this helps!
From http://api.jquery.com/jQuery.getJSON/ there is an example that includes 2 '?' in the URL.
you only have one, so try
$.getJSON('http://127.0.0.1:1337/getData?callback=?', function(rtndata) {
and see if that gets rid of your 404
then look #jimbojw suggestion for returning a proper jsonp formated responce.
Use this:
var express = require("express");
var server = express.createServer();
server.enable("jsonp callback");
server.get("/foo", function(req, res) {
// this is important - you must use Response.json()
res.json("hello");
});
jsonp with node.js express

Categories

Resources