I am used to working on httpd ( Apache ) which provides a way to configure subdomains which is mapped to a directory.
How can I do the same thing in Connect.js/Express.js ? I see that the only thing that I have is routes which I am not sure how I can use to configure sub domains. I have subdomains like m.mysite.com, sync.mysite.com
Can someone help ?
Or alternatively you could use vhost.
Then, create several sites in their own directory and export the express app, eg. /path/to/m/index.js:
var app = express()
/* whatever configuration code */
exports.app = app
// There is no need for .listen()
And then handle all requests with the following app:
var vhost = require('vhost');
express()
.use(vhost('m.mysite.com', require('/path/to/m').app))
.use(vhost('sync.mysite.com', require('/path/to/sync').app))
.listen(80)
Note that /path/to/m and /path/to/sync can be absolute paths (as written above) or relative paths.
You could append a subdomain to a request and then check for it in subsequent next() calls.
I got the following code from > http://groups.google.com/group/express-js/browse_thread/thread/b04bbaea7f0e8eed (so full credit to the original author)
app.get('*', function(req, res, next){
if(req.headers.host == 'some.sub.domain.com') //if it's a sub-domain
req.url = '/mysubdomain' + req.url; //append some text yourself
next();
});
// This will mean that all get requests that come from the subdomain will get
// /subdomain appended to them, so then you can have routes like this
app.get('/blogposts', function(){
// for non-subdomain
});
app.get('/mysubdomain/blogposts', function(){
// for subdomain
});
I have recently came across this problem, and wrote a module to help with it using express 4. https://www.npmjs.org/package/express-subdomain.
Example - api subdomain.
var express = require('express');
var app = express();
var router = express.Router();
//api specific routes
router.get('/', function(req, res) {
res.send('Welcome to our API!');
});
router.get('/users', function(req, res) {
res.json([
{ name: "Brian" }
]);
});
app.use(subdomain('api', router));
app.listen(3000);
Check out the module on npm to see more examples.
I created a module to help with subdomains in Express: https://github.com/WilsonPage/express-subdomain-handler
Do as I say, create two express app in different folder.
For example:
one app in /blogsite directory
const express = require("express");
const blog = express();
blog.get("/", (req, res) => {
res.send("BLOG SECTION");
});
blog.get("/allblogs", (req, res) => {
res.json([
{ title: "csgo major boston", description: "Best CSGO major ever" },
{ title: "Blast pro series", description: "Coolest series of CSGO" },
]);
});
module.exports = { blog };
and another one in /portfolio directory
const express = require("express");
const portfolio = express();
portfolio.get("/", (req, res) => {
res.send("PORTFOLIO SECTION");
});
portfolio.get("/resume", (req, res) => {
res.send("HERE'S MY RESUME");
});
module.exports = { portfolio };
Now create a main app in the outer folder and import the other two express apps that you just made in /blogsite directory and /portfolio directory.
And in the main app do this,
const express = require("express");
const vhost = require("vhost");
const { blog } = require("./blogsite");
const { portfolio } = require("./portfolio");
const app = express();
// BLOG AND PORTFOLIO
// url: http://blog.localhost:3002/
// url: http://blog.localhost:3002/allblogs
// url: http://portfolio.localhost:3002/
// url: http://portfolio.localhost:3002/resume
app
.use(vhost("portfolio.localhost", portfolio))
.use(vhost("blog.localhost", blog));
// MAIN APP ROUTES OR ENDPOINTS
// url: http://localhost:3002
// url: http://localhost:3002/myhobbies
app.get("/", (req, res) => {
res.send("MAIN APP SECTION");
});
app.get("/myhobbies", (req, res) => {
res.send("MAIN APP -> myhobbies section");
});
app.listen(3002, () => {
console.log("started listening");
});
fileStructure at the end should be looking like this
main(folder)
index.js (main express app which you need to run using node or nodemon)
blogsite(folder that I talked about for blog.localhost)
index.js (blog express app)
portfolio(folder)
index.js (portfolio express app)
I've had this exact same requirement for a project I was working on and ended up throwing together a middleware-based solution. It allows you to define routers and view folders per subdomains.
Check it out on NPM https://www.npmjs.com/package/express-multiview
or GitHub https://github.com/daryl-cecile/express-multi-view#readme
Related
I am new on Node.js and I have app.js file like:
const express = require('express');
const app = express();
const port = 8080;
app.get('/', (req, res) => res.send('Hello World'));
app.listen(port);
console.log(`App running on http://localhost:${port}`);
I also have index.html file in the same folder with app.js. Here there is a HTML5 website.
When I run the project I can see Hello World text in browser, How can I show this HTML file from my app.js so when I deploy it, it should show me responsive HTML file instead of Hello World?
I tried
app.get('/',function(req,res) {
res.sendFile('index.html');
});
But didn't see a difference.
To make your code example work you'll need to specify an absolute path, try using this:
res.sendFile(__dirname + "/index.html");
Another way would be to use EJS (https://ejs.co/)
In your example, you could do the following:
Install EJS:
npm install ejs
Set the View Engine to EJS:
app.set('view engine', 'ejs')
- Move your index.html file to a folder called "views" and also rename the file to index.ejs
views/index.ejs
In your app.get() handler, use:
res.render('index')
Final Result:
const express = require("express");
const app = express();
app.set("view engine", "ejs");
const port = 8080;
app.get("/", (req, res) => {
res.render("index");
});
app.listen(port, () => {
console.log(`App running on http://localhost:${port}`);
});
(note: I also moved your console.log to inside app.listen)
I found this on another stack overflow question, it should work
fs.readFile(__dirname + '/views/test.html', 'utf8', function(err, text){
res.send(text);
});
In my cloud function:
const app = express();
app.use(multer().array());
app.post("/", (req, res) => {
console.log("hit", req.body.from);
console.log("hit", req.body.from);
return res.sendStatus(200);
});
const emailInboundWebhook = functions.https.onRequest(app);
module.exports = {
emailInboundWebhook
}
I get this in logs:
i functions: Beginning execution of "emailInboundWebhook"
> hit undefined
> hit undefined
i functions: Finished "emailInboundWebhook" in ~1s
But when the same endpoint served as an express app(outside cloud functions):
const express = require("express");
const app = express();
const multer = require('multer');
app.get("/", async (req, res) => {
res.status(200).json({foo: "Bar"});
})
app.use(multer().array());
app.post("/webhook", async (req, res) => {
console.log("hit",req.body.to);
console.log("hit",req.body.from);
res.sendStatus(200);
});
app.listen(80, () => {
console.log("App listening on 80");
})
Gives this:
hit a#some-email-inbound.some.url
hit Rahul Priyadarsi <myemailid#gmail.com>
The two results are for same email sent and these functions are fired as sendgrid webhooks which send multipart/form-data POST requests that contain details of the email sent to a#some-email-inbound.some.url from myemailid#gmail.com
I have no idea as to why the two results are different(I am testing them via ngrok and since the console log lines run, clearly the function is hit).
I had the same problem.
Take a look in this issue: https://github.com/expressjs/multer/issues/572
Switch from Multer to Busboy, is also a good option.
One thing: In this situation use https.Request (from cloud-functions) instead of Request from express.
So I recently moved my website from a single-page website to an express server. Now I changed the file paths, but I cannot get my css and js files to load.
As seen in the developer console, the GET request to https://<website>.com/public/css/main.css returns a 404.
This is the css link:
<link rel="stylesheet" type="text/css" href="../public/css/main.css">
This is my server:
const express = require('express');
const app = express();
const getpages = require('./router/getpages.js');
app.use('/', getpages);
app.use(express.static('public'));
// 404's
app.use((req, res) => {
res.status(404).send('Page not found or non-existant.<br><br>Home');
});
app.listen(3000, console.log('Running on port 3000'));
This is ./router/getpages.js:
const router = require('express').Router();
const path = require('path');
router.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../views/', 'index.html'));
})
module.exports = router;
This is the file structure:
Note, I could not find any other questions that helped me, before this is marked as a dupe again.
As can be seen from the documentation, you should not have public in the route
https://<website>.com/css/main.css should work as expected.
refer : https://expressjs.com/en/starter/static-files.html
For example, use the following code to serve images, CSS files, and
JavaScript files in a directory named public:
app.use(express.static('public'))
Now, you can load the files that are
in the public directory:
eg : http://localhost:3000/images/kitten.jpg
Express looks up the files relative to the static directory, so the
name of the static directory is not part of the URL.
I am currently using MySQL for the db instead of the popular mongodb, since that is the case there isn't much documentation out there as far as architecture and getting set up. This is my current structure
client
-- angular files
routes
-- index.js
views
-- 404 page
app.js
I don't understand how I can implement controllers or models into this structure. I'm currently grabbing data from the db or sending it with the routes..I'm not sure what the added layer of controllers would do. Maybe this is a dumb question but I would just like to have a clear baseline so that my project will scale well. I feel like there should be way more to this than what I currently have.
index.js
const express = require('express');
const mysql = require('mysql');
const router = express.Router();
const db = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'db'
});
// Connect
db.connect((err) => {
if(err){
throw err;
}
console.log('MySql Connected...');
});
// Select Data
router.get('/getData', (req, res) => {
let sql = 'SELECT * FROM data';
let query = db.query(sql, (err, results) => {
if(err) throw err;
console.log(results);
res.send(results)
});
});
module.exports = router;
app.js
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const compression = require('compression');
const helmet = require('helmet')
const expressSanitizer = require('express-sanitizer');
const index = require('./routes/index');
const app = express();
const port = 3000;
var corsOptions = {
origin: 'http://localhost:8100',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
// var logger = (req, res, next) => {
// console.log('logging...')
// next();
// }
//added security
app.use(helmet())
// //set logger
// app.use(logger)
//cors options
app.use(cors(corsOptions))
//body parser middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
// Mount express-sanitizer here
app.use(expressSanitizer()); // this line follows bodyParser() instantiations
//set static path
app.use(express.static(path.join(__dirname, 'client')));
// set our default template engine to "ejs"
// which prevents the need for using file extensions
app.set('view engine', 'ejs');
//gzip compression
app.use(compression())
//set views for error and 404 pages
app.set('views', path.join(__dirname, 'views'));
app.use('/', index);
app.use('/fp/trips', trips);
app.listen(port, () => {
console.log('server started on port 3000')
})
When working on Node apps I tend to favor a scheme where controllers are (almost) services -- I think it works really well for small applications.
This is an example:
index.js
let app = express()
let users = require('./services/users')
app.get('/users/:id', async function(req, res, next) => {
try {
res.json(users.getByid(req.params.id))
} catch() {
next(err)
}
})
app.listen(8080)
services/users.js
let db = require('./db')
async function getById(id) {
let conn = await db.connect()
let user = conn.query('SELECT * FROM user WHERE id = ?', [id])
if (!user) {
throw new Error("404")
}
return user
}
module.exports = {getById}
services/db.js
let realDb = require('some-open-source-library-to-interact-with-db')
realDb.initialize(process.env.DB_CREDENTIALS) // pseudo-code here
module.exports = realDb
This though, won't work well when you're building large, complex apps -- I think you will require more structure in that case.
PS: I wouldn't suggest to build a large, complex app ever -- split it into smaller ones where patterns like the one I presented work nicely.
You can use Sequelize as ORM (Object Relational Mapper) for your MySQL DB to make your code more readable and to allow you to create better structure of your app. It also has support for PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL.
There are samples out there how to integrate Sequelize with Express. I'm not sure if I'm allowed to post a github repository here but here it is:
https://github.com/jpotts18/mean-stack-relational
PS. I don't own this repository but this might help you somehow.
I'm completely new to node.js but i'm trying to implement it on my personal site so that I start learning it. I have the node server running but i'm trying to set up the routing using express.js . All my files are typical static files .html, .js, .cs, .png , etc. Currently, the route gives me my index page on the 'home' page which is goo. If I attempt to navigate to the index of another diectory, I just get the 404 error page. My file structure is like this:
Server.js
package.json
node_modules
-- views (Folder)
-index.html (File in views)
--Projects (Folder in Views)
-index.html (File in Projects)
my Server.js looks like
var express = require("express");
var app = express();
var router = express.Router();
var path = __dirname + '/views/';
router.use(function (req, res, next) {
console.log("/" + req.method);
next();
});
router.get("/", function (req, res) {
res.sendFile(path + "index.html");
});
router.get("/Projects", function (req, res) {
res.sendFile(path + "Projects/index.html");
});
app.use("/", router);
/*app.use("*", function (req, res) {
res.sendFile(path + "404.html");
});*/
app.listen(3000, function () {
console.log("Live at Port 3000");
});
I've looked for the past ~18 hours at various resources and i'm just missing something i'm sure. My current idea of the issue is the navigation links in the html, however I've attempted changing those with no progress.
If you have only public file (like html, css, ..) you can put everything on a /public folder and add this instead of a router.
app.use(express.static('public'))
Doc: https://expressjs.com/en/starter/static-files.html
Every file will be accessible:
/public/my-folder/my-file.png > www.my-dmain.com/my-folder/my-file.png