Express and Cheerio/JSDOM - javascript

I am trying to get Cheerio to work with Express.
I'd like to be able to manipulate the dom from the server, but all I have found is web scraping..
There are some requirements..
At the moment, I am able to run multiple app.listen(port); statements, and use multiple servers.
I'm trying to append <script>alert("test);</script> to every single page sent by express.
I've created the express server: (Assuming Path is a predefined variable)
var express = require('express');
var app = express();
app.get('/', function (req, res) {
app.use(app.static(Path));
res.sendFile(Path + "/index.html");
});
app.listen(Port);
Can you guys provide me with a working example to append this to the page. Is there a way to get this to work in real time?
Thanks!

Here's a quick/simple example with no error handling:
var express = require('express');
var fs = require('fs');
var cheerio = require('cheerio');
var app = express();
app.get('/', function (req, res) {
fs.readFile(Path + '/index.html', function(err, data) {
var $ = cheerio.load(data);
$('body').append('<script>alert("test");</script>');
res.send($.html());
});
});
app.listen(Port);
I just tested that locally and it worked as expected. Be sure to test err inside the readFile callback in your real implementation and handle things appropriately if the file isn't found or there's an error reading it.

Related

Subdomains not working using express-vhost

new to Stack Overflow.
So I'm hosting my website using Express (Node 9) on a Digital Ocean droplet. I'm using express-vhost so I can detect subdomains to allow me to do api.example.com instead of example.com/api but when I try it, it just directs me to example.com while still having the api. part in the hostname.
I'm not sure if this is a programming problem or if it's actually something to do with my DNS records or maybe Digital Ocean is the problem. I'm not well equipped with knowledge of VPSes and hosting.
Here's the code:
// app.js
var subdomain = require('express-vhost');
var express = require('express');
var app = express();
var router = express.Router();
var api = require("./api.js")
subdomain.register('api.localhost:3000', api)
app.use(subdomain.vhost(app.enabled('trust proxy')));
app.get('/', function(req, res) {
res.send('Detect Region and send to correct subdomain!');
});
app.listen(3000);
and the other file
// api.js
var express = require('express')
var router = express.Router()
router.get('/', function(req, res) {
res.send("api url")
});
module.exports = router;
Sorry if this isn't enough information. Happy to answer any other questions you need answered.
-- sys
I suggest you not to use express-vhost (old and deprecated package) but directly the vhost module of the express org.
const vhost = require('vhost')
const express = require('express')
const app = express()
const api = require('./api')
app.enable('trust proxy')
app.use(vhost('api.localhost:8000', api)) // api being your router
app.get('/', function(req, res) {
res.send('Detect Region and send to correct subdomain!');
})
app.listen(3000)

Express / Node sendFile weird behavior

I'm trying to combine Node/Express and serve React files but its not working as desired.
server.js (my own REST API)
var express = require('express')
var app = express()
var public = __dirname + "/../frontend/build";
app.use(express.static(public));
app.get('/', (req, res) => {
res.sendFile(public + "/index.html");
});
app.get('/api/g', (req, res) => {
res.send("Test")
})
app.listen(3001);
My React build is in the public variable location.
Now when I go to localhost:3001 where my node server runs, I get this page
Page
but the issue is when I go to localhost:3001/api/g I still get the same page. Meaning, I dont get my "res.send" part, I have no idea why this is happening. Can anyone familiar with Node/Express help me out?

Multiple level of routing using Express.js with Node.js

I'm new to javascript. I'm trying to make a RESTfull API using Node.js and Express.js
My directory structure is as follows
/server.js
/api/api.js
/api/location/location.js
I want to make the API modular. I want that all the requests (get/post/delete/push) beginning with /api/* to be handled by api.js and whatever routing be required, api.js should route it to proper module.
For example, if someone requests GET /api/location/abc/xyz then api.js will transfer control to location.js which will then transfer to abc.js which will finally transfer to xyz.js stored in directory /api/location/abc/xyz/xyz.js
How can I achieve this?
Code so far:
/server.js
var express = require('express');
var app = express();
var api = require('./api/api.js');
var location = require('./api/location/location.js');
//app.use('/api/location', location); //This works, but I want api.js to handle sub-routes!
app.use('/api', api);
app.get('/', function(req, res){
res.end('successful get/');
});
app.listen(12345);
/api/api.js
module.exports = function(req, res, next) {
res.end('successful get /api');
next();
};
//Add code to handle GET /api/location
/api/location/location.js
module.exports = function(req, res, next){
res.end('from location!');
next();
}
You would use express.Router([options]).
And write it that way:
/api/api.js
var router = require('express').Router();
router.get('/location', require('./api/location') );
module.exports = router;
/api/api/location.js
module.exports = function(req, res, next){
res.end('from location!');
}
And don't call next(); if you ended the response. You only call next() in your callback if you don't handle the response.
I don't know how complex your REST api will be later. But try to to keep the routing in a small number of file. Having a callback for the routing in an own file like /api/api/location.js is most likely not the best idea.

express.static breaks nodejitsu application

I have no idea why this happens, but when I add a static path to my app I get an error on page of a hosting company I am using "nodejitsu" saying that application is not working, the line I am referring to is commented out in a code snippet below 'server.js' that is on the same level as my 'public' directory. I'm trying to think of a work around or other solution to define my public directory, but no luck so far, as I don't understand what could be causing an error. application uses node.js with dependencies including express and socket.io, latest versions.
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
//app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
io.on('connection', function (socket) {
});
The express term is not defined because you didn't save it.
You will need to do something like this:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));

NodeJS/Express app.use sequence and usage

I tried to separate my node routing into two parts: HTML/App and REST. Here is what I've done:
app.js:
var appPort = process.env.PORT || 80;
var express = require('express');
var http = require('http');
var appRouter = require('./routes/index');
var restRouter = require('./routes/rest');
var app = express();
var srv = http.createServer(app);
app.set('port', appPort);
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api/rest/', restRouter); // this seems not working .. I never get the expected response
app.use('/', appRouter); // I get this even with localhost/api/rest/...
var server = srv.listen(app.get('port'), function() {
debug('Express server listening ' + server.address().address + ':' + server.address().port);
});
index.js:
var express = require('express');
var router = express.Router();
router.get('/*', function (req, res) {
res.send('HOME')
});
module.exports = router;
rest.js
var express = require('express');
var router = express.Router();
router.get('/api/rest/*', function(req, res) {
res.send('REST API');
});
module.exports = router;
My questions:
1. It's possible in general to build multiple routers in this way?
2. Does the sequence of get.use matter, and/or do I have to deal with 'next'?
3. In case I would like to access a database inside the router can I hand over a parameter like this:
// ...
var client = new pg.Client(dbConnection);
// ...
app.use('/', appRouter(client));
1) It is possible to build multiple routers this way.
Because you are using this:
app.use('/api/rest/', restRouter);
your route calls in rest.js will be relative to /api/rest/ which means your code should be modified in rest.js to look like this:
router.get('*', function(req, res) {
res.send('REST API');
});
I would also encourage you to see the Express multi-router example on GitHub. It illustrates this point very clearly by showing a REST app with versioned routes.
2) The order of things matter
See the Express documentation for app.use and you will note:
Middleware functions are executed sequentially, therefore the order of
middleware inclusion is important.
If you reverse the order of your app.use calls, the router.get('/*', function (req, res) { line in index.js will catch everything before you get to other routes...defeating your purpose.
Also, if you don't call next, Express has no way to know that you are done or even that you want to continue to the next middleware or route.
3) The database question is a modules/scope question
This is more of a scope question than an Express question. I'd suggest looking up some of the excellent writing about javascript scope and also on how Node handles modules.

Categories

Resources