I have a large program written in C# using Visual Studio that is running as a standalone executable complete with an extensive GUI interface. We want to add a web interface to the program in order to get most, if not all of the functionality available.
The first step I took was to add a web server to the C# executable and I linked in some web pages (html and css) and I was able to present some data as a test case and this worked.
We decided that it would be better to treat the standalone executable like a database where we would prefer to send requests to the get data and post data to store data.
I'm using Node.js framework and Express as my webserver. I have a number of web pages designed and I'm using javascript and some embedded javascript to render data on some of the web pages.
The issue I'm having is how do I process a selected route on one of my webpages to force the the .js file that is processing the route to go out and access the executable program that is running on the same computer at this moment to both get and set data in the executable program and then present it back on the web page.
HTML code (test_data_02.ejs)
<input class="LSNButton1" type="button" style="color:black; background:green;" value="Test Button B" onclick="window.location.href = '/get_test_02b'" />
Javascript (Express) (main.js)
const { json } = require("express");
const express = require("express"),
app = express(),
fs = require("fs"),
homeController = require("./controllers/homeController"),
errorController = require("./controllers/errorController"),
data_entry_03 = require("./public/js/data_entry_03"),
layouts = require("express-ejs-layouts");
app.set("view engine", "ejs");
app.use(layouts);
app.use(express.static("public")); //tell the application to use the corresponding public folder to serve static files
app.use(express.urlencoded({ //assists in reading body contents, parse incoming requests in url format
extended: false
}));
app.use(express.json()); //assists in reading body contents, parse incoming requests in json format
app.set("port", process.env.PORT || 3000);
console.log("MAIN MAIN MAIN"); //this only happens once on start up - this file is only executed on startup, everything is configured on startup
//MIDDLEWARE CODE
app.use((req, res, next) => { //this is a generic middleware function that will be called before any route is processed
homeController.middleWareFunction(req, res); //process this function before moving on to next route that was selected
//console.log(req.query); //from the browser: http://localhost:3000?cart3&jack=5, this results in a request to /?cart=3&jack=5, how do i make a post for this
console.log(`request made to: ${req.url}`);
console.log("");
next();
})
//app.use("/general_data", homeController.readDataFile); //run this function for every request made to the path beginning with this route - it does not imply it is a middleware that will run on this route before the get
//GET ROUTE CODE
app.get("/", homeController.showHome); //a specific route has been identified and the callback function assoicated with the particular route is specified
app.get("/specific_data", homeController.showSpecificData);
app.get("/general_data", homeController.showGeneralData);
app.get("/get_test_02b", homeController.getTest02B);
More Javascript (homeController.js)
I was hoping somewhere in 'getTest02B' or in 'getTestData02B' I would be able to send or request data from the executable program somehow. Maybe using a URL. I would obviously need to add code to my executable to process the requests to either send or receive data. I would like to be able to process the data as JSON, XML, or text data in both directions. I just can't see the mechanism to perform this operation.
exports.getTest02B = (req, res) => {
console.log("in exports.getTest02B");
displayInformation(req.url, "URL");
displayInformation(req.method, "METHOD");
displayEmptyLine();
getTestData02B(function (err, data) {
if (err)
return res.send(err);
res.send(data);
});
};
One comment on this issue was that I needed to make a http request to the C#
program. I understand that Node.js allows several connections per server to
make HTTP requests.
I'm using the code below and it is not working.
const req = http.request('http://192.168.1.222/ListAlarms.html', (res) => {
console.log('STATUS:${res.statusCode}');
});
req.end;
When I run this code there appears to be no response from the C# program.
From the editing environment where I wrote the code above, if I select the URL and press CONTROL and CLICK I end up launching another browser with the data being displayed because the C# program is currently running. This implies to me that at least the URL in the http.request statement is good. Just to confirm the URL was working I ran the C# program in the debugger and I was able to break on receiving the URL. The URL is good but I just can't seem to access the C# program from the Node.js environment using the same URL. Obviously I'm doing something wrong.
I assume that once I'm able to generate a http.request from the Node.js environment I would be able to control the flow of data to and from the C# program.
Any input would be appreciated.
Related
I am building my server and client using node express.
I want my HTML file first(Which is done by express static automatically) then JSON file next so that JSON data is displayed on my html file well.
This is my file structure
- index.js
- public
|
- index.html
|
- front-end.js
index.js
const express = require('express');
const app = express();
const names = {...}
app.use(express.static('./public'));
app.get('/', (req, res) => {
return res.json({names});
})
front-end.js
axios.get('/')
.then(res => {
console.log(res)
})
.catch(err => {
console.error(err);
})
index.html
<html>
...
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="front-end.js"></script>
</html>
But JSON data transferring part is not working. the only res I can get in axios is index.html file. It is done internally by express with static.
I looked through the document about express static options but found no clues yet.
Isn't there any other way that I can do while leaving express.static part? or Do I need to change the part?
A client (like a browser) makes an HTTP request. It then gets an HTTP response. A single HTTP response. You can't send multiple responses to a single request.
In this case, the browser makes a request for / and Express checks each route in turn until it finds a match. Since you have an index.html file in the directory you configured with static against / it serves that and never reaches app.get('/'.
That said, I have no idea what behaviour you expect from a single URL serving up both an HTML document and a JSON text. They are fundamentally very different things that get handled in very different ways.
Perhaps you want to make the data in the JSON text available to JavaScript running in the HTML document.
In that case:
give the endpoint handling the JSON a different path
use Ajax (e.g. with the axios library that you've loaded) to request that URL
use DOM manipulation to add the data to the document
I am trying to make a 'shower thoughts' app. It has three categories stored in arrays. Underneath each are nested the actual list of user posts that the user can see (as arrays) . Of course, a user wont be able to see others posts. I have a rasbpi I am using as a webserver. The way I thought of doing this is a bit of javascript code on the web server that contain two functions: One that adds a users post to an array (with the input arguements being the post itself) and one that returns the array so that the app can update. However, I have no idea how to CALL this js file on the web server from the application. How would I do this?
You will have to construct a web API for this. You can do this using NodeJS on the server and then send requests to this API in Android
Basically what you are trying to do is create a simple Server-Client Architecture.
There are multiple ways to do so. I am going to explain using NodeJS as the server and volley on the client (android) side.
Firstly you can use Volley, to create an API call from android, that would interact with the NodeJS API, which in turn will create the array and store it in either SQL or any other form you want.
For reference you can check out this two projects.
This is an Android app which is using Volley to communicate with the server.
This is the NodeJS Server which is a simple REST API.
You can also use this link to learn basics about NodeJS if you don't know.
This is the basic NodeJS code to create a server and then send a response to the client.
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.write('Hello World!'); //write a response to the client
res.end(); //end the response
}).listen(8080); //the server object listens on port 8080
This is the basic Android Volley code to make a request to the server.
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
textView.setText("Response is: "+ response.substring(0,5));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
textView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
If you don't understand any of these code you can comment below.
I have recently started using the Twilio platform to send SMS to my users. I am perfectly able to run the node.js file from the node terminal with the command:
node twilio.js
Now, my goal is to be able to send those SMS, but from my website. For instance, when the user provides his phone number and presses the "Send sms" button. How can I achieve this? I have been looking this up for a while and I came across Express platform, ajax post requests, http server, etc. But, I can't figure out how to use them. I currently make many ajax requests (POST and GET) on my site, but I'm not able to make a request to a node file.
Thanks in advance,
Here is the twilio.js file:
// Twilio Credentials
var accountSid = 'ACCOUNT SID';
var authToken = 'ACCOUNT TOKEN';
//require the Twilio module and create a REST client
var client = require('twilio')(accountSid, authToken);
client.messages.create({
to: 'TO',
from: 'FROM',
body: 'Message sent from Twilio!',
}, function (err, message) {
console.log(message.sid);
});
Being able to run any arbitrary script on your server from a webpage would be a huge security risk - don't do that. I'm not sure where you're hosting your site, or what technology stack you're running your site on, but since you mentioned Express and Node -- if you're using Express I'd recommend that you setup a route that handles an ajax request. When someone presses 'Send SMS' you send an ajax request to that route, and in the handler that gets invoked you place the Twilio logic.
Here is a very simple way to setup an Express request that calls you node module:
twilio.js:
// Twilio Credentials
var accountSid = 'ACCOUNT SID';
var authToken = 'ACCOUNT TOKEN';
//require the Twilio module and create a REST client
var client = require('twilio')(accountSid, authToken);
function sendSms(callback) {
client.messages.create({
to: 'TO',
from: 'FROM',
body: 'Message sent from Twilio!',
}, callback);
}
// Export this function as a node module so that you can require it elsewhere
module.exports = sendSms;
Here is a good start for Express.
server.js:
var express = require('express');
var app = express();
// Requiring that function that you exported
var twilio = require('/path/to/twilio.js');
// Creating a controller for the get request: localhost:8081/send/sms
app.get('/send/sms', function (req, res) {
twilio(function(err, message) {
if (err) res.send(err);
res.send('Message sent: ' + message);
});
});
// Creating an HTTP server that listens on port 8081 (localhost:8081)
var server = app.listen(8081, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});
Then you can run node server.js, go to your browser and go to the url: localhost:8081/send/sms and your message will be sent :)
I'd make it so the client sends a HTTP POST request to the server, and then the server will send the message on behalf of the client.
Easiest way is to use express. I'm a bit unsure of how you're serving your website from a Node.js app without using express. Do you have a custom solution or only a non-connected from end, or something like heroku or something? In any case, you can create a route that processes posts with the following:
app.post("send_twilio_message_route", function(req,res){
// this receives the post request -- process here
});
^ Note that doesn't actually create the express app. See my link below and they give examples of some of the nitty gritty and syntax.
So the above would be on the server, in your Node.js app. From the front-end client code that runs in the browser, you need to create a post. The easiest way and most likely way to do it is through $.post in Jquery. if you are using Angular there's a slightly different syntax but it's the same idea. You call post, point it to a url, and put in the body data.
Make the body of the post request contain data such the message, phone numbers,
authentication token maybe.
See this to be able to get the body from a post request and some more implementation details of how to set it up:
How to retrieve POST query parameters?
Depending on the nature of what you're doing you might consider having the sms processing stuff run separate from the actual web service. I would create the sms unique stuff as its own module and have a function retrieve the router so that you can mount is onto the app and move it about later. This might be overkill if you're doing something small, but I'm basically encouraging you to at the start put thought into isolating your services of your website, else you will create a mess. That being said, if it's just a small thing and just for you it might not matter. Depends on your needs.
Important: I highly encourage you to think about the malicious user aka me. If you don't add any authentication in the post body (or you could include it in the url but I wouldn't do that although it's equivalent), a malicious client could totally be a jerk and expend all of your twilio resources. So once you get it basic up in running, before deploying it to anything that people will see it, I recommend you add authentication and rate limiting.
Let me preface by saying that I have spent a considerable amount of time trying to figure out the solution to this problem but I have not discovered something that works. I am using node and want to share a variable between my app.js server file and a client side javascript file (demo.js).
I run node app.js to launch the server and demo.js runs in the client. I have tried using module.exports and export but when I try importing in the demo.js file or referring to the module.exports var I get errors. Maybe I'm approaching this is in the wrong way.
For example, I am trying to use the node wikipedia package to scrape data. I have the following in my app.js file:
var wikipedia = require('node-wikipedia');
wikipedia.page.data('Clifford_Brown', { content: true }, function(response) {
console.log(response);
export const response = response;
module.exports.data = response
});
In my demo.js file I have tried importing this response var and using the module.exports var but I have been unsuccessful.
Anyone have any solutions to this issue or different approaches I should take?
Browser javascript files run in the browser. node.js javascript files run on the server. You cannot directly export things from one to the other. They are on completely different computers in different locations.
It is very important for developers to understand the notion that server-side code runs on the server and client-side code runs on the browser. The two cannot directly call each other or reach the other's variables. Imagine your server is in a data center in Seattle and the browser is running on a computer in Venice.
See How to access session variables in the browser for your various choices described for a previous answer.
In a nutshell, you can have the server insert a javascript variable into the generated web page so that when the javascript runs in the web page on the browser, it can then access that variable in its own page. Or, you can create an Ajax call so the client can request data directly from the server. Or you can have the server put some data in a cookie which the Javascript in the browser can then access.
If the data is easily known by the server at the time the page is generated and you are using some sort of page template system, then it is very easy to just add a <script> tag to the generated page that defines one or more Javascript variables that contain the desired information. Then, the client-side Javascript can just refer to those variables to have access to the data.
To pass data in http there is a request message and response message and the data needs to be inside that message.
In the request you can either pass variables in the request URL
http://host_name/path?key=value
Or inside the request body or headers.
In the response you pass back variables in the response header or response body
First Example:
One way of processing a URL request from the browser explicitly while passing variables is to set up your server to render a html page with those variables embedded.
If you use a templating engine like jade, you can consume the sent variables directly into the template using res.render({ key: 'value' }) rather than using a promise based api call which would run when the user performs some action on the client.
For instance.
// SERVER setup rendering engine
app.get('/', function(req, res) {
res.render( 'index', { key: 'value' })
}
Which will render index.html to the client with the key-value pair passed to the template file used to serve up the index.html (for example jade or ejs).
Second Example:
Using axios you can set up an action to call a server api (you can also pass variables in the URL, headers or body). Using the promise pattern you can then use these variables after the server api has responded.
// CLIENT setup axios
axios.get(URL + '/getkeyvalue')
.then(function(response) {
const value = response.data.key
})
On you server using express you (this is where you would get the optional request variables mentioned above) send back response variables in the body like this.
// SERVER setup express
app.get('/getkeyvalue', function(req, res) {
res.send({ key: 'value' })
}
Note that these are simple examples.
They are too completely different systems. The best way to accomplish what you're trying to do is the create a variable in your html on the server side by stringifying your data
<script> var my_data = <%= JSON.stringify(data) %> </script>
Thats an example using ejs, a common templating language in expressjs
Really fast, this question may have already been asked, but I am not totally clear on the terminology and have had no success when searching for a solution.
I am attempting to create a simple web application that can receive get and post requests. Then, I would like to take the information I receive from these requests and use them in a javascript file embedded in html that is displayed. I think it may be more clear with code. This is my app.js:
var express = require('express');
var app = express();
var assert = require('assert');
app.use(express.static('javascript'));
app.get('/', function(req, res) {
res.render('index.jade');
});
app.listen(3000);
I would then like to be able to take information received from a get or post request, specifically in JSON format, and then be able to use it in javascript that I have linked to index.jade. To make matters slightly more confusing in index.jade the only line is:
include map.html
So ideally I would be able to get the information to javascript in that html file.
I want to be able to pretty continuously update map.html using javascript based on frequent get and post commands.
This could be a very simple solution, I am pretty new with web application programming in general, and I have been struggling with this problem. Thanks in advance, and ask if you need any clarification.
I think you need to understand what you are doing. You are creating a web server using node.js. Express framework simplifies that for you. The official documentation of express is pretty great. You should refer that especially this link.
Now, in your application, you need to create endpoints for GET and POST requests. You have already created one endpoint "/" (root location) that loads your home page which is the contents of the file index.jade. A small example is :
app.get('/json', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ a: 1 }));
});
Jade is a templating engine which resolves to HTML. You should refer its documentation as well. Since as you said, you are not very familiar with these, you could simply use HTML as well.
After this tasks are quite simple. In your javascript, using ajax calls you can access the GET or POST endpoints of your server and do the desired actions.
Hope it helps!
The way I get it you want to be able to call an endpoint (lets assume /awesome) pass some info and then write to a Javascript file that you can then reference in your html.
Something like the below would write a main.js file in your public folder. You can make it write whatever you want.
var fs = require('fs');
fs.writeFile("/public/main.js", "console.log('Hello!')", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
You can then reference /public/main.js in your html.
Check that: Writing files in Node.js
If I misunderstood your intentions, apologies. :)
So you want to reviece continuously data from the server maybe web sockts are an option for you http://socket.io/docs/
This way u will open a stable connection from the client to the server. This is a great way if u want to get updates done by other clients.
If you want to trigger the changes by the client then ajaxs calls(http://www.w3schools.com/ajax/) as hkasera mentioned are the way to go.