for a recent project of mine I need to pass two functions from my server (written in node.js) to a client javascript tag. Actually to be completly correct, the client side javascript calls an XML request and I want to return some data and two functions for him which he should be able to use.
Second thing is I want to store a javascript function into a database in the server and then fetch it if the client requests it.
Anyone knows how this can be archieved and has some experience with it?
Note: you should really consider doing this in an HTTPS connection.
OK, so you want to receive code from the server and run it on the client. You could inject a script tag to the body and let the browser execute it. However, since you trust the code. I would simply use an eval call since that's what you'll doing anyway.
Here's how it would look in an Express app:
// server
function hello() {
alert('hello');
}
app.get('/get/js/code', function (req, res) {
res.send({
code: hello.toString(),
start: 'hello()'
});
});
// client (with jQuery)
$(function () {
$.getJSON('/get/js/code', function (json) {
eval(json.code + ';' + json.start + ';');
});
});
Related
I know how to send an http request to a server using angular js. With the promise returned, I know how to listen for a response and manipulate the ui thereafter. But this approach cannot be used for what I have in mind.
However, what I cannot figure out, is how to send a request to a website.
I have a server localhost:800/receiveData which receives a POST request and then manipulate the UI and DoM on the angularjs site
app.get('/', function(req,res){
res.sendFile(__dirname+'/index.html')
})
app.post('/receiveData', function(req,res){
var data = req.body.data
// assume data is a boolean
if(data){
//show a view in index.html using angular js or anything else
}else {
//show a different view in index.html
}
});
Any help will be greatly appreciated. I have a need for angular js. Having a SPA is imperative. I am completely open to adding additional stacks if neccessary.
EDIT:
As pointed out by MarcoS, manipulation of dom should ideally not happen from the server side. I am combining IPFS with node js and angular js to develop a single page application. The swarm of nodes set up using IPFS has an open line of communication with my server (by design). Based on packets of data sent via the comm line to my server, I need to convey messages to the user via the index.html.
I think your approach is wrong: on server-side, you should NOT manipulate the UI and DOM...
You should just do server activity (update a database, send an email, ..., return a static page).
Then you can output a result (JSON/XML/... format) for your client-side calling script to read.
Following OP edit, what I do understand is he wants server push to the client.
To get serve side pushes, you should poll on the client.
In a controller:
function getServerState(changeState) {
return $http.get("/receiveData").then(function(res) {
changeState(res.data); // notify the watcher
}).catch(function(e) {
/* handle errors here */
}).then(function() {
return getServerState(changeState); // poll again when done call
});
}
Consuming it this way:
getServerState(function(status) {
$scope.foo = status; // changes to `foo` $scope variable will reflect instantly on the client
});
And, server side:
app.post('/receiveData', function(req, res) {
var data = req.body.data; // assume data is a boolean
res.end(JSON.stringify(data);
});
I want to use an API in my meteor app. The API is restricted to a few requests per second per unique IP.
Does anyone know if the server IP or the user IP is used, when I make an API call in Meteor.methods like this
Meteor.methods({
searchTerm: function (term, lang) {
var parameters = {
"api_key": Meteor.settings.API
};
try {
var result = HTTP.call("GET", apiLink, { params: parameters });
return result.data;
} catch (e) {
return e;
}
}
}
Thanks in advance.
As already noted in the comments, if this code (the methods call itself) is runs on the server, then the method call (later with Meteor.call) is like a remote procedure call and the HTTP will be executed on the server only. If, however, this code, the methods call, is invoked on both the client and the server, then that defines a stub (http://docs.meteor.com/#/full/methods_header). That stub is executed in parallel on the client and the server. It is meant to help with latency compensation. I don't think you want that in this case though, since you are more concerned with the number of API requests. So I would suggest to leave it where it is right now (in the server folder somewhere). That way you can be sure that it will only execute on the server and not the client, and hence use the server IP.
I'm having an angular app(angular-seed app) which should call a function in nodejs(web-server.js).
The function in nodejs is just calls a batch file.
If I understood this correctly you want a click on the client-side (angular app) to call a batch file on the server side. You can do this in several ways depending on your requirements, but basically you want the client-side to send a http-request to the server (either with ajax call or form submit) and process this on the server that will call the batch file.
Client-side
On the client-side you need to have a button that uses the angular ng-click directive:
<button ng-click="batchfile()">Click me!</button>
In your angular controller you'll need to use the $http service to make a HTTP GET request to your server on some particular url. What that url is depends how you've set up your express app. Something like this:
function MyCtrl($scope, $http) {
// $http is injected by angular's IOC implementation
// other functions and controller stuff is here...
// this is called when button is clicked
$scope.batchfile = function() {
$http.get('/performbatch').success(function() {
// url was called successfully, do something
// maybe indicate in the UI that the batch file is
// executed...
});
}
}
You can validate that this HTTP GET request is made by using e.g. your browser's developer tools such as Google Chrome's network tab or a http packet sniffer such as fiddler.
Server-side
EDIT: I incorrectly assumed that angular-seed was using expressjs, which it doesn't. See basti1302's answer on how to set it up server-side "vanilla style" node.js. If you're using express you can continue below.
On the server side you need to set up the url in your express app that will perform the batch file call. Since we let the client-side above make a simple HTTP GET request to /performbatch we'll set it up that way:
app.get('/performbatch', function(req, res){
// is called when /performbatch is requested from any client
// ... call the function that executes the batch file from your node app
});
Calling the batch file is done in some ways but you can read the stackoverflow answer here for a solution:
node.js shell command execution
Hope this helps
The OP didn't mention express so I'll provide an alternative for the server side (Node.js part) without using any additional frameworks (which would require installing it via npm). This solution uses just node core:
web-server.js:
'use strict';
var http = require('http')
var spawn = require('child_process').spawn
var url = require('url')
function onRequest(request, response) {
console.log('received request')
var path = url.parse(request.url).pathname
console.log('requested path: ' + path)
if (path === '/performbatch') {
// call your already existing function here or start the batch file like this:
response.statusCode = 200
response.write('Starting batch file...\n')
spawn('whatever.bat')
response.write('Batch file started.')
} else {
response.statusCode = 400
response.write('Could not process your request, sorry.')
}
response.end()
}
http.createServer(onRequest).listen(8888)
Assuming you are on Windows, I would at first use a batch file like this to test it:
whatever.bat:
REM Append a timestamp to out.txt
time /t >> out.txt
For the client side, there is nothing to add to Spoike's solution.
Ok here is the twitter API,
http://search.twitter.com/search.atom?q=perkytweets
Can any one give me any hint about how to go about calling this API or link using Meteor
Update::
Here is the code that i tried but its not showing any response
if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to HelloWorld";
};
Template.hello.events({
'click input' : function () {
checkTwitter();
}
});
Meteor.methods({checkTwitter: function () {
this.unblock();
var result = Meteor.http.call("GET", "http://search.twitter.com/search.atom?q=perkytweets");
alert(result.statusCode);
}});
}
if (Meteor.isServer) {
Meteor.startup(function () {
});
}
You are defining your checkTwitter Meteor.method inside a client-scoped block. Because you cannot call cross domain from the client (unless using jsonp), you have to put this block in a Meteor.isServer block.
As an aside, per the documentation, the client side Meteor.method of your checkTwitter function is merely a stub of a server-side method. You'll want to check out the docs for a full explanation of how server-side and client-side Meteor.methods work together.
Here is a working example of the http call:
if (Meteor.isServer) {
Meteor.methods({
checkTwitter: function () {
this.unblock();
return Meteor.http.call("GET", "http://search.twitter.com/search.json?q=perkytweets");
}
});
}
//invoke the server method
if (Meteor.isClient) {
Meteor.call("checkTwitter", function(error, results) {
console.log(results.content); //results.data should be a JSON object
});
}
This might seem rudimentary - but the HTTP package does not come by default in your Meteor project and requires that you install it a la carte.
On the command line either:
Just Meteor: meteor add http
Meteorite: mrt add http
Meteor HTTP Docs
Meteor.http.get on the client is async, so you will need to provide a callback function :
Meteor.http.call("GET",url,function(error,result){
console.log(result.statusCode);
});
Use Meteor.http.get. Per the docs:
Meteor.http.get(url, [options], [asyncCallback]) Anywhere
Send an HTTP GET request. Equivalent to Meteor.http.call("GET", ...).
The docs actually include some examples of using Twitter, so you should be able to get started with them.
on server side if you provide the call back to http.get it will be asynch call so my solutions to that undefined return on client was
var result = HTTP.get(iurl);
return result.data.response;
as i did not pass a call back to HTTP.get so it waited until i got response. hope it helps
I want to send a javascript code to the socket.io server so that server broadcast to the clients and that code get executed .
what i tried i make a json variable like this .and send that via socket.io
var sent={
'code': function(){
console.log('javascript code');
}
};
socket.send(sent);
when i check at server the message comes is {} and same as it is to the other client .
what is wrong in this code , how should i send javascript code ?
Do not do this. You will open all listening clients to being hacked.
that said...
...you could follow pimbdb and pass the function in as a string, then use eval on the receiving end to execute it:
// on the sending client
var sent = {
"code": "function() { /* do something not evil */ }"
}
socket.send(sent);
// on the receiving client
socket.on('message', function(data) {
if (data.code) eval(data.code); // and pray.
});
Again, don't. Instead, pass some non-executable data that can then be interpreted in a limited number of non-malicious ways.
EDIT: Apologies, interpreted that as if you were executing code on the server. But client<-> client is XSS-prone, still.