Im a newbie on node.js, I just wanted to know how to extract the requested url in this code
app.use(express.static(__dirname+"/public"));
Thank you for your help
As you can see on the static middleware source, a middleware is basic a function that receives the parameters (request, response, next_function).
So you could create a function that reads the url before it goes to static middleware.
var express = require('express');
var app = express();
var staticfn = express.static(__dirname+'/public');
app.use(function (req,res,next) {
console.log(req.url);
var sendStream = staticfn(req,res,next);
console.log(sendStream.path);
});
app.listen(3000)
As you can see on the send package used by the static middleware, the send function returns a object called SendStream.
Related
In Node Js, on the entry file e.g. index.js, How can I get requested data either as Form-data or Form-URL-encoded or Raw JSON data in middleware?
In my project, I am handling various API request,
Few requests contain file type so requesting as form-data.
Few requests do not contain file type so requests are coming as Form-URL-encoded.
Now the main problem is before routing, I need a specific field from req.body in the middleware.
But I am getting req.body as undefined.
For reference here is my index.js file:
const express = require('express');
const app = express();
app.use(express.raw());
app.use(express.urlencoded({ extended: false }));
app.use((req, res, next) => {
const routes_handler = require('./routes/index.js')(app, express, req);
next();
})
app.listen(3000, () => {
console.log("Server running at Port " + 3000);
});
and the routes/index.js file as follows:
module.exports = function (app, express, req) {
console.log(req.body);
//I need here data of req.body for all requests type (form data, URL-encoded, raw JSON)
app.post('/', function (req, res) {
console.log("Here I can get the requested body easily", req.body)
res.send('Hello World');
});
app.post('*', function (req, res) {
res.send({
code: 0,
message: 'No Content',
status_code: 204,
data: {
error: 'API not found!'
}
});
});
}
Also, I know for file type data, POSTMAN will send the request as Form-data, not as Form-url-encoded. So which I should choose Formidable or Multer?
The way you get all the data in index.js is by creating middlewares for your application, every time any routes that go into your application will be passed through this middleware.
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
The below middleware will simply listen to all routes & adds up request time to request time, here goes the code
let express = require('express')
let app = express()
let bodyParser = require("body-parser")
app.use(bodyParser.json())
let requestTime = function (req, res, next) { // simply updating add the requestBody using the middleware
req.requestTime = Date.now();
req.json_body = req.body;
next()
}
app.use(requestTime) // requestTime is the middleware here
app.get('/', function (req, res) {
var responseText = 'Hello World!<br>'
responseText += '<small>Requested at: ' + req.requestTime + '</small>'
res.send(responseText)
})
app.listen(3000)
Few things to note here
Always add interceptor above all routes
Don't forget to add next() inside the middleware, else it will not go to the next route.
Now, coming to the second part of your question which is accessing body,formdata, etc
You can use body-parser npm module to achieve that, something like this
Starting from Express 4, body-parser comes inbuilt with it, so you can try out something
app.use(express.json());
app.use(
bodyParser.urlencoded({
extended: false
})
);
Now, the last bit, you don't need Multer for formdata, but for file upload like multipart/form-data you will need this. Both are good in their own ways, I would go for Multer.
Hope this will help you :)
I believe the body-parser module is your answer.
https://www.npmjs.com/package/body-parser
Add the following line before the routes in your index.js after installing the body-parser package.
app.use(bodyParser.json())
I am attempting to make a simple AngularJS application that will pull from a RESTful API to fill out some "cards" on the screen.
Here is my Angular $http request (xxx.xxx.xxx.xxx is to hide my public IP):
$http({method : "GET", url : "http://xxx.xxx.xxx.xxx:9000/api/cards"}).then(function mySucces(response) {$scope.listData = response.data;});
This request works for actual JSON formatted calls, such as a call to http://data.consumerfinance.gov/api/views.json - it works great here.
However, it does not work when calling my RESTful API created with node-restful using nodejs. I can view the API data in the web browser, but I cannot get it to pull in the angular app. I am about 99.99% sure it is because I am not returning it as JSON format but mongodb format from my API.
I am asking for assistance to find a way to have my RESTful API return JSON formatting.
Here is my server.js:
// Dependencies
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var parth = require('path');
// Connect to Mongoose (MongoDB)
mongoose.connect('mongodb://localhost/rest_test')
// Build Express
var app = express();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
// Router
app.use('/api', require('./routes/api'));
// Start Server
app.listen(9000)
console.log('Yo, stuffs on port 9000')
Here is my routes.js:
// Dependencies
var express = require('express')
var router = express.Router();
// Models
var Card = require('../models/cards')
// Routes
Card.methods(['get', 'put', 'post', 'delete']);
Card.register(router, '/cards')
// Return Router
module.exports = router;
And here is my mongoose schema (cards.js):
// Dependencies
var restful = require('node-restful');
var mongoose = restful.mongoose;
// Schema
var cardSchema = new mongoose.Schema({
title: String,
author: String,
desc: String,
cardtype: String
});
// Return model
module.exports = restful.model('Cards', cardSchema);
One of my issues is that I do not know where I need to but the function(res, resp, next) in, which file and what should it look like?
Thanks in advance.
I Wiresharked it. It is totally sending JSON back. This is an issue with the application for whichever reason.
Thank you.
In your server.js file simple put this code.
`var logger= function (req, res, next) {
console.log('LOGGED');
next();
}; app.use(logger);`
I am using an express.js package called express-subdomain to facilitate requests to defined subdomains I set up.
As far as I understand, the subdomain constructor function expects an express router object which I pass to it from an exported router module.
What I have tried is as follows:
MAIN APP.JS SERVER FILE
var common = {
express: require('express'),
subdomain: require('express-subdomain')
};
common.app = common.express();
module.exports = common;
common.app.listen(3000, function () {
console.log(('app listening on http://localhost:3000'));
});
var router = require('./router/index');
// Error Handling
common.app.use(function(err, req, res, next) {
res.status(err.status || 500);
});
router/index
module.exports = function (){
var common = require('../app');
var router = common.express.Router();
common.app.get('/', function(req, res) {
res.send('Homepage');
});
common.app.use('/signup', require('./routes/signup'));
common.app.use(common.subdomain('login', require('./routes/login')));
}();
routes/login
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.send('login working');
});
router.get('/info', function (req, res) {
});
module.exports = router;
I have tried to access the login subdomain at the following urls:
http://login.localhost
http://login.localhost:3000
http://login.localhost.com
http://login.localhost.com:3000
Any clarification or assistance appreciated.
author of express-subdomain here đź‘‹
A couple of things:
Hosts must be setup correctly - I'd recommend something like so in your /etc/hosts file.
127.0.0.1 myapp.local
127.0.0.1 login.myapp.local
For more information on this see https://github.com/bmullan91/express-subdomain#developing-locally
Register the subdomain routes before any others, including the homepage route. The order is very important
The pattern you're using in /routes/index.js is not advised (requiring a self invoking function). Exporting the Router like you done in /routes/login.js is cleaner.
Finally, If you're still stuck take a look at the source for express subdomain and in particular its tests.
Happy coding.
I'm working on a small webapp that normally is built with a relatively complex process and then deployed to WebLogic.
However, the portion I'm working on is using AngularJS, and is all HTML and Javascript. It normally makes ajax calls into another webapp on the same domain. To shorten my development cycle, I'd like to avoid a build process and just reload the browser page.
I think I can do this with "node express", but the details escape me. I've managed to define a very simple app that just serves local files, but now I have to figure out how to detect some of those paths as matching an expression, and reroute those requests to a request to an external domain.
So, if it gets a request for "/diag/stuff.html", "/foo/thing.html", or just "/index.html", it will send back the file matching the same path. However, if the path matches "/fooService/.*", then I have to send back the response from a GET to the same path, but on a different host and port.
This is my trivial app so far:
var express = require('express');
var app = express();
app.use("/", express.static(__dirname));
app.listen(8000);
Update:
I like the proxy idea, so I did a local install of "http-proxy" (I forgot and first did a global install) then changed the script to this:
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var proxy = new httpProxy.RoutingProxy();
app.use("/", express.static(__dirname));
app.get('/FooService/*', function(req, res) {
"use strict";
return proxy.proxyRequest(req, res, {
host: "foohost.net",
port: 80
});
});
app.listen(8000);
This fails with:
<path>\server.js:4
var proxy = new httpProxy.RoutingProxy();
^
TypeError: undefined is not a function
at Object.<anonymous> (<path>\server.js:4:13)
What might be wrong here?
Update:
Would it be useful to see the contents of "console.log(httpProxy)" after that "require"?:
function ProxyServer(options) {
EE3.call(this);
this.web = this.proxyRequest = createRightProxy('web')(options);
this.ws = this.proxyWebsocketRequest = createRightProxy('ws')(options);
this.options = options;
this.webPasses = Object.keys(web).map(function(pass) {
return web[pass];
});
this.wsPasses = Object.keys(ws).map(function(pass) {
return ws[pass];
});
this.on('error', this.onError.bind(this));
}
Does that provide a clue for why "new httpProxy.RoutingProxy()" says it's undefined?
You can use http-proxy and forward requests to different host. To install http-proxy you need to run sudo npm install http-proxy. Code that will handle proxy will look like that:
httpProxy = require('http-proxy');
proxy = new httpProxy.RoutingProxy();
(...)
app.get('/fooService/*', function (request, response) {
"use strict";
return proxy.proxyRequest(request, response, {
host : externalHost,
port : 80
});
});
UPDATE
Above code is working for http-proxy ~0.10.x. Since then lot of things had changed in library. Below you can find example for new version (at time of writing ~1.0.2):
var httpProxy = require('http-proxy'),
proxy = httpProxy.createProxyServer({});
(...)
app.get('/fooService/*', function (request, response) {
"use strict";
return proxy.web(request, response, {
target: 'http://fooservice.com'
});
});
If redirects meet your need, then that's the easiest solution:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(app.router);
app.get('/fooService/*', function(req, res){
res.redirect(302, 'http://otherdomain.com:2222' + req.path);
});
app.listen(8000);
Note that it's generally considered good practice to use a subdirectory for your static files (like public above). Otherwise you could view your app file itself and anything else you keep in your application root!
I am trying to understand how vhost actually works in Express JS. Here's a working code sample (forgot where I pulled this from):
// -- inside index.js --
var EXPRESS = require('express');
var app = EXPRESS.createServer();
app.use(EXPRESS.vhost('dev.example.com', require('./dev').app));
app.listen(8080);
// -- inside dev.js --
var EXPRESS = require('express');
var app = exports.app = EXPRESS.createServer();
app.get('/', function(req, res)
{
// Handle request...
});
Now, my question is, why do we call createServer() twice? Why does this even work? Is vhost internally "merging" the two servers together?
Node.js is event-driven, and when a request comes in, the request event is raised on a http.Server. So basically, express.vhost (or really, connect.vhost) is a middleware function which raises the request event on another instance of a http.Server:
function vhost(req, res, next){
if (!req.headers.host) return next();
var host = req.headers.host.split(':')[0];
if (req.subdomains = regexp.exec(host)) {
req.subdomains = req.subdomains[0].split('.').slice(0, -1);
server.emit('request', req, res);
} else {
next();
}
};