cannot set node and express to serve files - javascript

I use Windows 7. I installed nodes 0.10.12 and latest version of express and express-generator both globally. I
created a new express project named nodetest1 and installed all dependencies succesfully using npm install.
Going to http://localhost:3000/ renders Express Welcome to Express -so it works.
I try to use node and express as simple server now, just use some html files.
According to the book "Jump Start Node.js" by Don Nguyen Copyright © 2012 SitePoint Pty. Ltd. [pages 9-11] , I edited my
app.js file and added
var fs = require('fs');
and after
var routes = require('./routes/index');
var users = require('./routes/users');
I added
app.get('/form', function(req, res) {
fs.readFile('./form.html', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
});
Then I created a simple form.html file put it in the nodetest1 directory, restarted my server and in the command line I get
app.get('/form', function(req, res) {
TypeError : Cannot call method 'get' of undefined
npm ERR! weird error 8
npm ERR! not ok code 0
What am I doing wrong? I just want to use simple html, not Jade.
Also do I have to edit the app.js for every html file I add? And where will I add the new files, in what folder?
Thanks in advance

Did you create the express app?
var express = require('express');
var app = express();
Also, you can just use res.sendFile for this.
app.get('/form', function(req, res) {
return res.sendFile('form.html');
});
If you are serving up a lot of static files you may want to look into express.static middleware.
http://expressjs.com/4x/api.html#app.use
This will serve up all files you put in your public directory:
app.use(express.static(__dirname + '/public'));
Directory structure:
|-app.js
|-public
| |-index.html
| |-form.html
You're form.html will be served to localhost:3000/form.html
If you wan't to serve up html files without an extension you can use the solution found in this other answer to a different question by #robertklep.
Any way to serve static html files from express without the extension?
app.use(function(req, res, next) {
if (req.path.indexOf('.') === -1) {
var file = publicdir + req.path + '.html';
fs.exists(file, function(exists) {
if (exists)
req.url += '.html';
next();
});
} else {
next();
}
});
You'll want this to be before app.use(express.static(__dirname + 'public'));
Note: The book you mentioned was published Dec 2, 2012. Express 3 was released Oct 23, 2013 according to github. The current version is 4.8.5. You may want to use a more current reference.

Related

Can't set static folder express.js

I'm trying to set a static folder for my index.html file and other folders like css, img and js scripts.
but i don't manage to set a static folder successfully.
this is my app.js code:
const path = require('path');
const express = require('express');
const app = express();
app.use(express.static(path.join(__dirname, 'httpdocs')))
// app.get('/', (req, res) => {
// res.sendFile('index.html')
// });
const PORT = process.env.PORT || 5000
app.listen(PORT, (err) => {
if (err) {
console.log(err);
}
console.log(`Listening on port ${PORT}`);
})
my file tree is like this:
---node/
------httpdocs (i want this to be static folder
---css/
---js/
---img/
--index.html (this file should be loaded when loading the root link)
---app.js (nodejs script)
p.s: im using plesk on windows so if this makes any difference tell me.
I can see the only error is in below line.
app.use(express.static(__dirname + 'httpdocs'))
Try to print below tow different method using console :
console.log(__dirname+ 'httpdocs');
console.log(path.join(__dirname, 'httpdocs'));
Output:
...\nodehttpdocs
...\node\httpdocs
I hope you get the solution.
If you are trying to manually merge path then you have to add path separator '\' externally
Ex: app.use(express.static(__dirname + '\httpdocs'));
Or else use below method
Ex: app.use(express.static(path.join(__dirname, 'httpdocs')));
I suggest using path.join method. Because it will add path separator based on the operating system. Or else you have to manage manually.

Questions on to use Node.js as local server with Braintree?

I'm not new to JavaScript but I am new to Node.js and back end languages. I have a very simple question.
I've installed and setup Node.js on my computer and I'm attempting to get a server going between my static files & directory(s) and my browser to be able to send and receive requests. I've downloaded Braintree's free Sandbox (found here) for practice to get some faux transactions going just to gain a better understanding of how this can work.
I set up a local server by running npm install -g http-server on my command line and then http-server to set it up.
I then received the following message in my command line:
Starting up http-server, serving ./public
Available on:
http://127.0.0.1:8080
http://10.0.1.4:8080
Hit CTRL-C to stop the server
So, with this setup...if I wanted to do get() and post() methods and see it rendered and communicating between my "server" and my static files. How do I do this? For example, if I were to set up Braintree's sandboxed environment and then create a clientToken using the following code from Braintree's website
const http = require('http'),
url = require('url'),
fs = require('fs'),
express = require('express'),
braintree = require('braintree');
const gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: "xxxxx",
publicKey: "xxxxx",
privateKey: "xxxxx" //blocked out real numbers for privacy
});
Here is the remaining code I hae to create a "client Token" for a transaction...and here is the guide I'm following via Braintree's website...
http.createServer((req,res) => {
gateway.clientToken.generate({
},(err, response) => {
if(err){
throw new Error(err);
}
if(response.success){
var clientToken = response.clientToken
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(clientToken);
res.end("<p>This is the end</p>");
} else {
res.writeHead(500, {'Content-Type': 'text/html'});
res.end('Whoops! Something went wrong.');
}
});
}).listen(8080,'127.0.0.1');
So, my question is...if I wanted to generate send a token to a client using the get() method...how would I do that? Would it have to be a separate js file? How would they be linked? If they're in the same directory will they just see each other?
Here is an example on Braintree's website of how a client token may be sent:
app.get("/client_token", function (req, res) {
gateway.clientToken.generate({}, function (err, response) {
res.send(response.clientToken);
});
});
How could this be integrated into my current code and actually work? I apologize if these are elementary questions, but I would like to gain a better understanding of this. Thanks a lot in advance!
I don't know much about braintree, but usually you would use somthing like express.js to handel stuff like this. So I'll give you some quick examples from an app I have.
#!/usr/bin/env node
var http = require('http');
var app = require('../server.js');
var models = require("../models");
models.sync(function () {
var server = http.createServer(app);
server.listen(4242, function(){
console.log(4242);
});
});
So that's the file that gets everything started. Don't worry about models, its just syncing the db.
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
// share public folder
app.use(express.static(path.join(__dirname, 'public')));
require('./router.js')(app);
module.exports = app;
next up is the server.js that ties eveything together. app.use() lines are for adding middleware and the app.use(logger('dev')); sets the route logger for what your looking for.
app.use(express.static(path.join(__dirname, 'public'))); shares out all files in the public directory and is what your looking for for static files
var path = require('path');
module.exports = function(app){
//catch
app.get('*', function(req, res){
res.sendFile(path.join(__dirname, '..', 'public', 'index.html'));
});
}
last piece is the router.js. This is were you would put all of you get and post routes. generally I've found that if you see app.get or app.post in examples there talking about express stuff. It's used a lot with node and just makes routing way easier.
Also if your using tokens a route would look like this.
app.get('/print', checkToken, function(req, res){
print.getPrinters(function(err, result){
response(err, result, req, res);
});
});
function checkToken(req, res, next){
models.Tokens.findOne({value: req.headers.token}, function(err, result){
if(err){
res.status(500).send(err);
}else if(result == null){
console.log(req.headers);
res.status(401).send('unauthorized');
}else{
next();
}
});
}
so any route you want to make sure had a token you would just pass that function into it. again models is for db

Node JS - HTML Paths

I recently have the problem that I dont get how the paths for html in node js work. I link my index.html's scripts as normal - relative to the index.html's file (node.js file and index.html are in the same directory "res.sendFile(__dirname + '/index.html');"). But if I open it up in the Browser executed with node js it just stats "cant GET blabla" for the scripts. Instead opening it up by just clicking index.html without node js those paths work! How do I have to write html paths for node js?
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
port = Number(process.env.PORT || 3000),
server.listen(port);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
Thanks for your time! :)
Look at this:
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
You have told Node "When the browser asks for / give it index.html".
What happens when the browser asks for someScript.js?
You haven't told Node what to do then.
(You'll probably want to find a library for serving up static files rather than explicitly handling each one individually).
you should configure express to server static files, for example, put all the static files under a directory called 'public'
var express = require('express');
var app = express();
var path = require('path');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(8080);
ExpressJS to Deliver HTML Files
Render HTML file in ExpressJS
You can use
app.use(express.static(path.join(__dirname, "folder-name")));
Usually i put all my static files in a separate folder named "assets"
The I set up a static route as shown below:enter code here
app.use('/assets', express.static('assets'));
When you write:
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
It will only serve index.html file, not the other js scripts and stylesheets which you have added in your html.
There are 2 ways to solve that:
For both of them, I would suggest to use 'path' module.
Solution 1:
var path = require('path')
app.get('/path/to/js/foo.js',function(req,res){
res.sendFile(path.resolve(__dirname,'/path/to/js/foo.js')
})
app.get('/path/to/css/bar.css',function(req,res){
res.sendFile(path.resolve(__dirname,'/path/to/css/bar.css'))
})
and so on for every .css and.js file you have added in your index.html.
Solution 2:
You can create a public dir in your project's root dir. Inside which all your img, css and js files will be there.
Next,
var path = require('path')
app.use(express.static('public'))
app.get('/',function(req,res){
res.sendFile(path.resolve(__dirname,'/index.html')
})

Calling a file from local machine as a web service Javascript

I am working on a project. Where i need to call a web service which returns a SOAP message. Now the problem is that the webservice is hosted on an IntraNet and i can not access it. I have been provided with a txt file that contains a sample response of the web service.
I have to manipulate the reply in my code
Is there anyway I can call this txt file instead of the web service and get the response and manipulate it ?
You can do that using node and Express JS.
Install Node from www.nodejs.com
after installing and running node, go to your directory and install express :
npm install express
then create a file called app.js and run it with node : node app.js
app.js file:
var express = require('express')
, app = module.exports = express();
app.get('/', function(req, res){
res.send('<p>Static File Server for files</p>');
});
app.get('/txt/:file(*)', function(req, res, next){
var file = req.params.file
, path = __dirname + '/public/txt/' + file;
res.sendFile(path);
});
if (404 == err.status) {
res.statusCode = 404;
res.send('File Does Not Exist!');
} else {
next(err);
}
});
if (!module.parent) {
app.listen(8023);
console.log('Express started on port 8023');
}
put the folder that has your txt file in /public/txt/ so public and the app.js are in the same directory. you should run the app.js with node after this is done.
go to your web browser : navigate to localhost:8023/txt/yourfile.txt and if everything is working find you should be able to get the file.

Render raw HTML

I want to render raw .html pages using Express 3 as follows:
server.get('/', function(req, res) {
res.render('login.html');
}
This is how I have configured the server to render raw HTML pages (inspired from this outdated question):
server
.set('view options', {layout: false})
.set('views', './../')
.engine('html', function(str, options) {
return function(locals) {
return str;
};
});
Unfortunately, with this configuration the page hangs and is never rendered properly. What have I done wrong? How can I render raw HTLM using Express 3 without fancy rendering engines such as Jade and EJS?
What I think you are trying to say is:
How can I serve static html files, right?
Let's get down to it.
First, some code from my own project:
app.configure(function() {
app.use(express.static(__dirname + '/public'));
});
What this means that there is a folder named public inside my app folder. All my static content such as css, js and even html pages lie here.
To actually send static html pages, just add this in your app file
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/layout.html');
});
So if you have a domain called xyz.com; whenever someone goes there, they will be served layout.html in their browsers.
Edit
If you are using express 4, things are a bit different.
The routes and middleware are executed exactly in the same order they are placed.
One good technique is the place the static file serving code right after all the standard routes.
Like this :
// All standard routes are above here
app.post('/posts', handler.POST.getPosts);
// Serve static files
app.use(express.static('./public'));
This is very important as it potentially removes a bottleneck in your code. Take a look at this stackoverflow answer(the first one where he talks about optimization)
The other major change for express 4.0 is that you don't need to use app.configure()
If you don't actually need to inject data into templates, the simplest solution in express is to use the static file server (express.static()).
However, if you still want to wire up the routes to the pages manually (eg your example mapping '/' to 'login.html'), you might try res.sendFile() to send your html docs over:
http://expressjs.com/api.html#res.sendfile
Have you tried using the fs module?
server.get('/', function(req, res) {
fs.readFile('index.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
}
as the document says : 'Express expects: (path, options, callback)' format function in app.engin(...).
so you can write your code like below(for simplicity, but it work):
server
.set('view options', {layout: false})
.set('views', './../')
.engine('html', function(path, options, cb) {
fs.readFile(path, 'utf-8', cb);
});
of course just like 2# & 3# said, you should use express.static() for static file transfer; and the code above not suit for production
First, the mistake you did was trying to use the express 2.x code snippet to render raw HTML in express 3.0. Beginning express 3.0, just the filepath will be passed to view engine instead of file content.
Coming to solution,
create a simple view engine
var fs = require('fs');
function rawHtmlViewEngine(filename, options, callback) {
fs.readFile(filename, 'utf8', function(err, str){
if(err) return callback(err);
/*
* if required, you could write your own
* custom view file processing logic here
*/
callback(null, str);
});
}
use it like this
server.engine('html', rawHtmlViewEngine)
server.set('views', './folder');
server.set('view engine', 'html');
Reference
Official express 2.x to 3.x migration guide
See 'Template engine integration' section in this url
https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x
After a fresh install of the latest version of Express
express the_app_name
Creates a skeleton directory that includes app.js.
There is a line in app.js that reads:
app.use(express.static(path.join(__dirname, 'public')));
So a folder named public is where the magic happens...
Routing is then done by a function modeled this way:
app.get('/', function(req,res) {
res.sendfile('public/name_of_static_file.extension');
});
*Example:*
An index.html inside the public folder is served when invoked by the line:
app.get('/', function(req,res) {
res.sendfile('public/index.html');
});
As far as assets go:
Make sure the css and javascript files are called from the folder relative to the public folder.
A vanilla Express install will have stylesheets, javascripts, and images for starting folders. So make sure the scripts and css sheets have the correct paths in index.html:
Examples:
<link href="stylesheets/bootstrap.css" rel="stylesheet">
or
<script src="javascripts/jquery.js"></script>
You can render .html pages in express using following code:-
var app = express();
app.engine('html', ejs.__express);
And while rendering, you can use following code:-
response.render('templates.html',{title:"my home page"});
I wanted to do this because I'm creating a boilerplate NodeJS server that I don't want tied to a view engine. For this purpose it's useful to have a placeholder rendering engine which simply returns the (html) file content.
Here's what I came up with:
//htmlrenderer.js
'use strict';
var fs = require('fs'); // for reading files from the file system
exports.renderHtml = function (filePath, options, callback) { // define the template engine
fs.readFile(filePath, function (err, content) {
if (err) return callback(new Error(err));
var rendered = content.toString();
// Do any processing here...
return callback(null, rendered);
});
};
To use it:
app.engine('html', htmlRenderer.renderHtml);
app.set('view engine', 'html');
Source: http://expressjs.com/en/advanced/developing-template-engines.html
Comments and constructive feedback are welcome!
After years a new answer is here.
Actually this approach like skypecakess answer;
var fs = require('fs');
app.get('/', function(req, res, next) {
var html = fs.readFileSync('./html/login.html', 'utf8')
res.send(html)
})
That's all...
Also if EJS or Jade will be used the below code could be used:
var fs = require('fs');
app.get('/', function(req, res, next) {
var html = fs.readFileSync('./html/login.html', 'utf8')
res.render('login', { html: html })
})
And views/login.ejs file contains only the following code:
<%- locals.html %>
app.get('/', function(req, res) {
returnHtml(res, 'index');
});
function returnHtml(res, name) {
res.sendFile(__dirname + '/' + name + '.html');
}
And put your index.html to your root page, of course you could create a /views folder for example and extend returnHtml() function.
You can send file using res.sendFile().
You can keep all html files in views folder and can set path to it in options variable.
app.get('/', (req, res)=>{
var options = { root: __dirname + '/../views/' };
var fileName = 'index.html';
res.sendFile(fileName, options);
});

Categories