I need Express server to serve static files (website). It works in my code well:
var express = require('express');
var app = express();
var path = require('path');
var p = path.join(__dirname, '../web/public');
app.use("/files", function (req, res) {
return res.send("I will do something on server");
});
app.use(express.static(p));
app.use('/*',express.static(p));
let port = 80;
var server = app.listen(port);
But when I have a form served by this server, it redirects after submit, and the page displays only something like
Cannot POST /dashboard/
How can I correctly handle post requests within the meaning of serving static files? I tried to add this right before declaring the port:
app.post(express.static(p));
app.post('/*', express.static(p));
But it doesn't work.
PS: my entire page is served (I want that) from index.html. In order to do that, I have in my code that:
app.use(express.static(p));
app.use('/*',express.static(p));
How do I "redirect" post requests to index.html? In this file I have the entire app logic (it is a single page app).
PS2: I really need default submit. Going around that is not a solution for me (I want to offer the user to save their login and password, and without submitting the form, Google chrome will not offer that to users). And on the other side I really need use POST, as the login form is transferring sensitive data...
Any ideas?
Thanks!
There is no file called dashboard so there is nothing for express.static to serve.
To handle that dashboard route, you can do this:
app.post("/dashboard", function (req, res) {
return res.send("I will do something with this post");
});
If you want to redirect 404 traffic to index.html, you can do this after all your route definitions:
app.use("/", function (req, res) {
return res.redirect("/index.html");
});
Related
I have some server side code in node js, which creates a express js object and runs the server. The app loads the index.html page which is inside the public folder. I have never written the code to serve the home page (mention below), still it works.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
I have not written this code so how does the index.html gets rendered. My understanding says express JS looks for the first instance of index.html page in all the static folders declared in the code and renders it, in my case the static folder is "publimc" and it has index.html at the root level.
server code follows below, which I have written.
var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('contactlist', ['contactlist']);
var bodyParser = require('body-parser');
app.use(express.static(__dirname + '/publimc'));
app.use(bodyParser.json());
app.get('/contactlist', function (req, res) {
console.log('I received a GET request');
db.contactlist.find(function (err, docs) {
console.log(docs);
res.json(docs);
});
});
app.listen(8000);
console.log("Server running on port 8000");
The home page is rendered as part of the express.static middleware default options.
To disable this logic, set express.static(..., { index: false }).
If you want to change the file served as a home page, set express.static(..., { index: 'yourfile.html' }).
What this option does, in fact, is attempt to serve an index page with given file name for each directory in your public folder, so if you have public/foo/index.html then it will get served when requesting /foo/ path.
I am trying to redirect localhost:9000 to localhost:9000/list after the user clicks on a button in home page and use a get method to display list.html. How can I use the AJAX call I have in display.js and the get request in my routes.js to redirect url and serve up my list.html. When I click on the button, nothing happens. To change url i tried both windows.location and location.href but I am not sure if these are even needed.
Directory layout
dir main
-server.js
dir subMain
dir display
-display.js
dir routing
-routes.js
dir public
-home.html
-list.html
server.js
var path = require('path');
var express = require('express');
var app = express();
require('./subMain/routing/routes.js')(app, path, express);
app.listen(9000, function(){
console.log('connected on 9000')
})
routes.js
module.exports = function(app, path, express){
app.use(express.static("app"))
app.use(express.static(__dirname + "/public"));
app.use(express.static(__dirname + "/routing"));
app.use(express.static(__dirname + "/display"));
app.use(function(request, response, next){
response.sendFile(path.join(__dirname + "/..", "public", "home.html"));
})
app.get('/list', function(request, response){
response.sendFile(path.join(__dirname + '/..', 'public', 'list.html'));
});
}
display.js
$(document).on('click', '#btn', sendSurvery);
function sendSurvery(){
window.location = 'survey.html';
//var myQueryUrl = "http://localhost:9000/survey";
//$.ajax({url: myQueryUrl, method: 'GET', success: function(result){
// location.href = "http://localhost:9000/list"
//}}).done(function(response){
//});
}
Update: Since AJAX is not required to change html on browser, where would be a suitable place to use the windows.location, and how would I connect that to a get request to my list.html? Right now, I tried doing a get request in both the server.js file and routes.js file, but when I click on the button, the url will change to survey but not the content on the browser (list.html is not displaying)
Update 2: I got rid of the AJAX call and just used: windows.location = localhost:9000/list but the get request is not sending the list.html file to the browser. I tried putting the get request in the server.js file also, but it still will do nothing
You don't need AJAX here (A stands for Asynchronous) - you can simply do window.location = http://localhost:9000/survey
This will effectively tell browser to send a synchronous GET request to the server and replace current page with whatever it receives as response.
not sure if this is what you are looking for, but there is no survey.html in your listed tree structure....
also, if you want to do relative access, you may want to add a line similar to the below:
app.use(express.static(path.join(__dirname, 'subMain/public')));
display.js
$(document).on('click', '#btn', sendSurvery);
function sendSurvery(){
var myQueryUrl = "http://localhost:9000/";
window.location.replace(myQueryUrl + 'survey.html)
}
This would allow you to actually store myQueryUrl as a config variable elsewhere so that it could be changed based on your environment.
You also have to make sure that you link to display.js in your html file so it's initially requested from the server. The server won't just send it for you.
And you don't show the rest of your file but you might need to initializing the call to the click handler if you aren't doing that:
(function(){
$(document).on('click', '#btn', sendSurvery);
}();
As a note, GET requests (and all requests for that matter) originate on the Client and are sent to the server. So they must be placed in files being sent to the client.
I am attempting to build a single page app using Express.js. On my index.html page, I have a basic form, which upon submit will make a request to an API, retrieve the data, parse it, and then I want to render the parsed data as a list of links. Right now I am able to render the index page, and I can make the submission call to the API from the form that I added to the page. What I am confused about is how to properly redirect the data I get from the API call and then render it on the same page. I've built simple apps using Express before where there were multiple views, but never a single page app. For those apps, I know that for the response you could call something like res.render('name of view to render', data), but that is not working in this case. I've tried to find some solutions through this site and via the Express docs, but I have not seen anything that didn't also include using another framework like Angular. For the purposes of this app, I need to not include any additional frameworks, and I am a bit lost.
My function for calling the API looks like this right now. When it is called, I am directed to a page that just has the json displayed
app.use(express.static(path.join(__dirname, '/public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use('/', express.static(path.join(__dirname, 'public')));
app.get('/search', function(req, res) {
var title = req.query.movieTitle;
var url = 'http://www.omdbapi.com/?s=' + title;
request(url, function (err, response, body) {
var results = JSON.parse(body);
var movieTitles = results.Search;
console.log(movieTitles);
res.send(movieTitles);
});
});
The basic thing you have to do is:
define routes which your back-end app has to respond with the spa
send your "skeleton" file to the response on that routes
Example code:
const handler = (req, res) => res.send(path.join(__dirname, "path/to/your/index.html"))
const routes = ["/", "/hello", "/world"]
routes.forEach( route => app.get(route, handler) )
This should get you started
A Node.js app needs to:
1.) receive data from another serve that calls /some_endpoint,
2.) process the data it receives to create a String result jwtString,
3.) redirect the user to the root / url of the AngularJS app while passing the jwtString as a res.header included inside the res.redirect.
What specific changes need to be made to the Node.js routing code below in order for the _jwt header to be successfully passed from the Node.js app to the client AngularJS at at /?
app.get('/some_endpoint', function(req, res) {
//Process data from another server that was redirected here.
//then send the result of that processing in jwtString while
//redirecting user to the root url of the Angular app that
//is served by this Node.js instance.
res.setHeader('_jwt', jwtString);
res.redirect('/');
});
app.get('*', function(req, res) {
var queryData = url.parse(req.url, true);
console.log('in get *, queryData is: ');console.log(queryData);
res.sendfile('./public/index.html'); // load the single view file (angular will handle the front-end)
});
When I run the code above, I cannot seem to find the _jwt header in the Network tab of the FireFox developer tools.
I am building a webservice, for which i am using nodejs, phantomjs and expressjs. I am learning all the three.
I want to serve a delayed response to the clients after processing their query. Like for example,
I am processing certain inputs from my client, then, i want to process the data at the backend which will take approx 10 sec on an avg. Then i wanted to serve this page to the client.
Is it possible in node to send multiple responses to the same request or delayed responses so that the template will automatically update the contents.
Or , should i use the same method , like store the json in a file in the server , then serve the page with ajax which will query the page.
please help me. here is the code which i wrote ,
app-server.js(the main file):
// import express module
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// define all required template files to be served and also define the template engine
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
// Useful modules
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// import the routes
require('./router')(app);
app.listen(8080);
router.js:
var crypto = require('crypto');
var express = require('express');
module.exports = function (app) {
// define the static routes.
app.use('/static', express.static('./static'));
app.use('/media', express.static('./media'));
//defining the controller.
var parserlib = require('./controller.js')
// Define the home root path
app.get('/', function (req, res) {
// shows the home search page.
res.render('index', {content:'template success'});
});
app.get('/search', function(req, res){
res.redirect('/');
});
app.post('/search', parserlib.parserlib);
}
controller.js:
var crypto = require('crypto');
var path = require('path')
var childProcess = require('child_process')
exports.parserlib= function(req, res){
var output = '';
var url = req.body.search_url;
var childArgs = [
path.join(__dirname, 'external-script.js'),
url,
]
// execute the script in a separate thread.
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
// handle results
console.log(stdout);
output = stdout;
//console.log(err);
//res.send(output);
});
//res.send(output);
};
so , what i want to see is, first send a response to client stating that its loading, then i want to update the with processed data. In other languages its not possible to send multiple responses. Not sure about nodejs.
Also, do i have to store the json output from the processed lib to a file and then use ajax to query ? or is it possible to directly update the json object to the client ?
Thanks
This is just not how HTTP works. The clients won't expect it. This has nothing to do with Node or any other framework. The way to do what you're attempting is to actually send a response that the thing is loading, and then have some other mechanism for reporting state.
As an example, you might design a RESTful API. In that RESTful API you might define a endpoint for creating new things:
POST /api/things
The client would post data to that to create a new thing. The response should be something that provides a location of the newly created resource, for example an HTTP 301 to /api/things/1.
If the user goes to /api/things/1 and the thing isn't done getting made yet, then you can either do a temporary redirect (303) to /api/things/1/status which provides some helpful status information, or just issue a 404.
If you actually want to send back server-side pushes of status information, then you should be looking at WebSockets or a pure Socket API of some kind, neither of which is provided by Express, but both of which are available in Node (checkout the socket.io library and the net core library)