Subdomains not working using express-vhost - javascript

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)

Related

How to serve static files in ExpressJS on some paths and not others

How can I serve static files with ExpressJS only from some of paths, while not for others?
To be more specific, I want to serve static files from all paths except /files (in case of request to this path, I want only to edit some file on the server).
I have this piece of code:
var express = require('express');
var app = express();
express.static(__dirname);
app.use(redirectUnmatched);
function redirectUnmatched(req, res) {
//Do something on server
console.log("req.url:"+req.url+"<br>"+__dirname);
}
let port = 80;
var server = app.listen(port);
But I really don't know, how to edit my code to do that...
Can anyone help me?
Thanks!
Just defining the /files route before serving the static files might work:
// Define `/files` route first
app.use("/files", function (req, res) {
return res.send("I will be served instead of a files directory");
});
// Static
app.use("/", express.static(__dirname));
const express = require('express');
const path = require('path');
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
app.get('/',(req,res)=> {
res.sendFile(path.join(__dirname,'static','index.html');
});
app.listen(3000);

How to import routes in polka js similar to express.Route()

I am trying to import route logic from another file. In express js this is achievable via express.Route(), when i tried polka.Route() an error pops up saying Route doesn't exist in polka.
Express Implementation
server.js
const express = require('express');
const users = require('./routes/api/users');
const app = express();
app.use('/users', users);
user.js
const express = require('express');
const router = express.Router();
router.get('/test', (req, res) => res.json({ msg: 'works' }));
module.exports = router;
When /users/test is hit the output is {msg:'works'}. This works for the express implementation. For the polka implementation i changed the word express to polka installing it. The issue arises on the line polka.Router() of user.js. How do i enable this functionality of importing route logic from another file in polka.
The polka micro web server does not implement a difference between routers and the app. In your users.js file simply setup your routes as you would in your server.js file and then module.export. See Below:
Polka Implementation
server.js
const polka = require('polka');
const users = require('./routes/api/users');
const app = polka();
app.use('/users', users);
user.js
const polka = require('polka');
const router = polka();
router.get('/test', (req, res) => res.end(JSON.stringify({ msg: 'works' })));
module.exports = router;
Hope this help!
Also, here is a good link to see other differences between Express.js and Polka.js: https://github.com/lukeed/polka#comparisons

Module.Exports not working for Express

I'm trying to organize routes in express. But I'm having trouble getting a simple setup to work. I have two files, api.js, which has the routing info, and index.js, which runs the server.
However, when I try this, I get no response on localhost:3000.
api.js
var express = require('express');
module.exports = function() {
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the home page!');
});
return router;
}
index.js
var express = require('express');
var app = express();
var router = require('./api');
app.use('/',router);
app.listen(3000);
console.log('Listening on port 3000!');
However, when I change api.js to this, it works:
api.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the home page!');
});
module.exports = router;
I don't understand why the bottom api.js works when the top one doesn't. Shouldn't module.exports return the same express Router in both cases?
The difference is that in the first version you're exporting a function that returns the router vs the second version where you're exporting the router itself.
In the first version, Express calls your exported function, passing it req and res, expecting it to somehow handle the request. The exported function of course is not designed to handle a request (it's just creating a router and returning it), so the request times out.

Express and Cheerio/JSDOM

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.

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