How to interact with a node.js script in the browser? - node.js

I'm unfamiliar with node and don't know where to start looking, or what exact question to ask.
I have a server on which I can run javascript through node. So:
node myfile.js
Now, I want to be able to browse to this server, passing a query string variable:
https://myserver.com/somefile.html?somevariable=1
Then, I want to pass the somevariable to the node script myfile.js, get the result back from myfile.js, and present the result in the browser.
How do I do this?
I'd happily call myfile.js directly in the browser, too, but that won't run the script through node nor would it output the result to the browser.
(More specifically, I want to pass the value of somevariable from a PHP page on another server and then process the result on that PHP page.)

So if I understand your question correctly, you want to create an API in NodeJS.
Take a look at: https://github.com/expressjs/express
const express = require('express')
const app = express()
app.get('/someRoute', function (req, res) {
console.log(req.query.somevariable)
res.send(`Some Variable: ${req.query.somevariable}`)
})
app.listen(3000)
https://localhost:3000/someRoute?somevariable=1

Related

Serve both static and apis in express in production

I have deployed a express/vue app to production.
I'm finding a bit difficult to serve both static files and APIs from express.
Inside expressfolder/app.js
const app = express()
const path = require('path')
const serveStatic = require('serve-static')
...
// index.html and static/css, static/js - bundle made with npm run build
const DIR_DIST = path.join(__dirname, '../../path/to/dist')
app.use(serveStatic(DIR_DIST))
...
app.get('/tests', (req, res) => {
res.send({msg: 'Hello there!'})
})
When i go to myapp.com, I see the index.html as desired.
If I type directly in the browser myapp.com/tests I see the raw msg "hello there" from express.
If i call the same route via the link inside index.html, I receive this error in chrome
(failed) net::ERR_CONNECTION_REFUSED
It's working on my local machine, so I'm sure it's some kind of messy config I haven't set properly.
Also, I don't want to be able to access /tests directly: vue-router should override that, but it's a lesser problem.
It's probably been asked before, but it's been a while and I haven't found a solution yet.
Thanks.
The error ERR_CONNECTION_REFUSED is a fundamental networking error that occurs before your server code actually gets to run so that would likely have nothing to do with your specific server code.
It probably happens because you have a bad URL in your web page.

Register new route at runtime in NodeJs/ExpressJs

I want to extend this open topic: Add Routes at Runtime (ExpressJs) which sadly didn't help me enough.
I'm working on an application that allows the creation of different API's that runs on NodeJs. The UI looks like this:
As you can see, this piece of code contains two endpoints (GET, POST) and as soon as I press "Save", it creates a .js file located in a path where the Nodejs application is looking for its endpoints (e.g: myProject\dynamicRoutes\rule_test.js).
The problem that I have is that being that the Nodejs server is running while I'm developing the code, I'm not able to invoke these new endpoints unless I restart the server once again (and ExpressJs detects the file).
Is there a way to register new routes while the
NodeJs (ExpressJs) is running?
I tried to do the following things with no luck:
app.js
This works if the server is restarted. I tried to include this library (express-dynamic-router, but not working at runtime.)
//this is dynamic routing function
function handleDynamicRoutes(req,res,next) {
var path = req.path; //http://localhost:8080/api/rule_test
//LoadModules(path)
var controllerPath = path.replace("/api/", "./dynamicRoutes/");
var dynamicController = require(controllerPath);
dynamicRouter.index(dynamicController[req.method]).register(app);
dynamicController[req.method] = function(req, res) {
//invocation
}
next();
}
app.all('*', handleDynamicRoutes);
Finally, I readed this article (#NodeJS / #ExpressJS: Adding routes dynamically at runtime), but I couldn't figure out how this can help me.
I believe that this could be possible somehow, but I feel a bit lost. Anyone knows how can I achieve this? I'm getting a CANNOT GET error, after each file creation.
Disclaimer: please know that it is considered as bad design in terms of stability and security to allow the user or even administrator to inject executable code via web forms. Treat this thread as academic discussion and don't use this code in production!
Look at this simple example which adds new route in runtime:
app.get('/subpage', (req, res) => res.send('Hello subpage'))
So basically new route is being registered when app.get is called, no need to walk through routes directory.
All you need to do is simply load your newly created module and pass your app to module.exports function to register new routes. I guess this one-liner should work just fine (not tested):
require('path/to/new/module')(app)
Is req.params enough for you?
app.get('/basebath/:path, (req,res) => {
const content = require('content/' + req.params.path);
res.send(content);
});
So the user can enter whatever after /basepath, for example
http://www.mywebsite.com/basepath/bergur
The router would then try to get the file content/bergur.js
and send it's contents.

Parameter restriction with Node.js

What I want to do is check the script URL for a parameter & display the content of that parameter like:
www.mywebsite.com/mynodescript.js?parameter=i+am+new+to+node!
Now I want to display "I am new to node!" on browser screen and if the parameter is not present I just want to exit.
edit:
I found this code but I am not sure how to deploy it
var url = require('url');
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
Note: i want to upload my script on heroku & want it to call it remotely
When you say you don't know how to deploy it, I'm assuming you don't have a http server setup yet?
Look at using Express (http://expressjs.com/). It's easy enough to get started with.
Create a file called app.js like this:
const express = require('express')
const app = express()
// This handles the path /mynodescript.js You can create a bunch of functions like this to handle different paths. See the express docs for more.
app.get('/mynodescript.js', (req, res)=>{
let parameter = req.query.parameter; // <-- Could also do let {parameter} = req.query This is where you would pull out your url parameters
if(parameter){
res.send(parameter); // <-- this sends it back to the browser.
}else{
res.status(422).end(); // <-- you can set a status here or send an error message or something useful.
}
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
Start the script using node app.js from the same directory.
Then open a browser and go to http://localhost:3000/mynodescript.js?parameter=i+am+new+to+node and you should see your parameter
Note that you will have to install express first npm install express --save
Note that you do not have to use express. There are quite a few http libraries available for nodejs. Or you can use the built-in http server (https://nodejs.org/api/http.html). It's good to get familiar with the NodeJS docs, but their http server is cumbersome to work with.

Scraping from Facebook

I have a challenge I'm running into and cannot seem to find an answer for it anywhere on the web. I'm working on a personal project; it's a Node.js application that uses the request and cheerio packages to hit an end-point and scrape some data... However, the endpoint is a Facebook page... and the display of its content is dependent upon whether the user is logged in or not.
In short, the app seeks to scrape the user's saved links, you know, all that stuff you add to your "save for later" but never actually go back to (at least in my case). The end-point, then, is htpps://www.facebook.com/saved. If, in your browser, you are logged into Facebook, clicking that link will take you where the application needs to go. However, since the application isn't technically going through the browser that has your credentials and your session saved, I'm running into a bit of an issue...
Yes, using the request module I'm able to successfully reach "a" part of Facebook, but not the one I need... My question really is: how should I begin to handle this challenge?
This is all the code I have for the app so far:
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', (req, res) => {
// Workspace
var url = 'https://www.facebook.com/saved';
request(url, (err, response, html) => {
if (err) console.log(err);
res.send(JSON.stringify(html));
})
})
app.listen('8081', () => {
console.log('App listening on port 8081');
})
Any input will be greatly appreciated... Currently, I'm on hold...! How could I possibly hit this end-point with credentials (safely) provided by the user so that the application could get legitimately get past authentication and reach the desired end-point?
I don't think you can accomplish that using request-cheerio module since you need to make a post request with your login information.
A headless browser is more appropriate for this kind of project if you want it to be a scraper. Try using casperJs or PhantomJs. It will give you more flexibility but it's not a node.js module so you need to make a step further if you want to incorporate it with express.
One nodeJs module I know that can let you post is Osmosis. If you can make .login(user, pw) to work then that'll be great but I don't think it can successfully login to facebook though.
API if possible would be a much nicer solution but I'm assuming you already looked it up and find nothing in there for what you are looking for.
My personal choice would be to use an RobotProcessAutomation. WinAutomation, for example, is a great tool for manipulating web and scraping. It's a whole new different approach but it can do the job well and can be implemented faster compared to programmatically coding it.

Converting Node.js command line app to web app

So this is more of an open ended question: I've started working with node and I've been creating command line applications for practice. The majority of these apps take command line arguments and make http requests to an API and serve up the results based on the arguments passed. The thing is, I would like these programs to have useful front-end interfaces so that the results are not just display via the command line terminal. Is there an easy way to accomplish this? Is this what Express is useful for?
perhaps more fully, that's what express is for and that's what routes do for you - so that your browser can be directed to a default (e.g. index.html) page or a specific page or service. If you're rendering basic html pages, stored in an /HTML folder, to the user, then you might have the following kind of code in your app:
var express = require('express');
var app = express();
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/HTML'));
followed by a series of app.get('path/from/browser') and/or app.post('path/from/broswer') statements which tell your nodejs server what to do when various get and post commands are sent to the app.
as your app gets more complex, you may want to consider the router service as a way to structure your application code and associated services.
you also need to start an http server, so the browser can actually talk to the server. You would do that in a very simple way by executing the following code:
var cfenv = require('cfenv');
var appEnv = cfenv.getAppEnv();
app.set('port', appEnv.port);
var server = app.listen(app.get('port'), function() {console.log('Listening on port %d', server.address().port);});
In this simple example, your app is now using 3 new services: express, ejs, and cfenv. You would use the standard npm install process to get this into your local app so that you can use them. From your application root folder, you would execute npm install --save express, repeating for each of the three new services.

Resources