I have written a simple server using node.js. At the moment the server responds by writing "hello world" to the browser.
The server.js file looks like this:
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8080);
I use this URL in the browser to trigger the "hello world" response:
http://localhost:8080/
I want to be able to open a basic html page when I pass a URL like this:
http://localhost:8080/test.html
I have looked through many tutorials and some stackoverflow posts but there was not much out there on this specific task. Does anyone know how to achieve this with a simple modification to the server.js file?
If you wish to open .html file through nodejs with the help of "http://localhost:8080/test.html" such url, you need to convert .html page to .jade format.Use rendering engine with the help of expressjs framework.Express rendering engine will help you to render .jade file on nodejs server.
It is better to use a front end javascript frameworks such as Angular, React or Vue to route to different pages. Though, if you want to do it in Node, you could do something like this using express:
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.sendFile('views/index.html', { root: __dirname })
});
app.get('/test', function(req, res) {
res.sendFile('views/test.html', { root: __dirname })
});
app.listen(8080);
This is an ok solution for static pages. Express is very useful for writing REST API's.
Related
Current code below
const http = require('http');
const server = http.createServer(function(req, res) {
res.setHeader("Content-type", "application/json");
res.setHeader("Access-Control-Allow-Origin", "*");
res.writeHead(200);
res.end("Ping server page");
});
server.listen(8080, function() {
console.eblue("\nListening on port 8080");
console.eblue("WEB SERVER STARTED\n");
});
I just want to know if their is a way to make a fully featured site and host it using node.js
I recommend using Express (a node.js package) for web servers, which you can then serve static files - including HTML - through with express.static.
Yes (if I understood correctly), you just need to serve the html as a static file like this:
https://expressjs.com/en/starter/static-files.html
I need the Nodejs-fileserver for saving some text but I want to do this with a website written in html.
How can I do something like this?
Here is an example but there only comes the failure: 'book() isn't defined'.
const http = require('http');
const fs = require('fs');
http.createServer( function (req, res) {
res.writeHead(200,{'Content-Type': 'text/html'})
res.write('<meta charset="utf-8">');
res.write('<button onclick="book(this)">Buchen</button>');
res.end();
}).listen(8080);
function book(sender)
fs.appendFile('test.csv',sender, function (err) {
if (err) {throw err};
console.log("Schreiben erfolgreich");
});
}
When I connect the nodejs file with the script tag, can I handle the code of the html file?
<script src="server.js"></script>
How can I execute the nodejs book() function with the html button?
You might need to read this answer first. Due to JavaScript, a single language on both client and server side, it might cause some confusion when you start with Node.js.
But, that doesn't mean you can't perform operations onClick from HTML. You surely can do it using Ajax or form submit. I would also suggest you to use Express.js framework.
Also, you can't include the file like this -
<script src="server.js"></script>
Because it's not a client-side normal JavaScript file even though it has .js extension. It is a server-side file.
Talking about example, you can do something like this -
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.get('/book', function(req, res) {
res.render('index');
});
When you visit /book route, it'll open an index view which might have a form to submit. Then you can write code within /post POST url to do further modification.
app.post('/book', function(req, res) {
// req.body will have submitted form data.
// You can then do modification.
// You need to use body-parser.
});
i have gone back to basics to try and create a simple example of calling a REST API, receiving some JSON back and rendering the JSON data in HTML using Jade.
I have tried many approaches to this but cannot get any to work.
what code would i need to add to my main script file (below - lxrclient.js) to achieve this. I know i need to add express module, and render the view, but no matter who may approaches i have tried i cannot get it to work. I have also added the jade file i am using further down. really appreciate any help anyone can provide with this.
//this is my main script file lxrclient3.js
var http = require('http');
var express = require('express');
var app = express();
app.set('view engine', 'jade');
var options = {
host: '41.193.214.130',
port: 2510,
path: '/eiftidemo/clt_list',
method: 'GET'
};
http.request(options, function(res) {
var body = '';
//node of these statemnst excecute
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var clientsData = JSON.parse(body);
debugger;
});
}).end();
app.get("/clientlist", function(req, res){
res.render('listlxr', {clientd: clientsData});
});
var server = app.listen(3000, function() {
console.log('Our App is running at http://localhost:3000');
});
here is my Jade view
html
head
title List of Clients
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css")
body
div.row
div.col-md-3
div.col-md-6
div.panel.panel-primary
div.panel-heading.text-center
h1 Client List for Hyposure
div.panel-body
table.table
each clients in clientsData
tr
td.media
span.bg-info= clients.clientName
td.media
span.bg-info= clients.clientSurname
thx to anyone who can help
First of all, when you say Jade I hope you mean Pug, if not, you should update to the newest version of Pug instead.
Now, to send data to your template for the engine to render you send a JSON object, like so;
res.get("/", function(req, res)
{
res.render("page.html", {greet : "Hello"});
}
This is a standard way of rendering a page and sending some data along side.
Now in your Pug (Jade (Same thing)) template you can access the sent variable like so;
html
head
title List of Clients
body
h1 #{greet} <!-- This will print "Hello" -->
This should give you a basic idea on how to render data onto a site, you can also send nested objects and you just work it the same way as in this example, but you point to the correct key. So for example if you're sending the following object:
{
greet: {
message : "Hello",
who : "Adrian"
}
}
Then you can print values from that using:
#{greet.message} #{greet.who}
I am creating web page with a button to load data from the server using Rest API build through ExpressJS, NodeJs.
var express=require('express');
var mysql=require('mysql');
var app=express();
var server=app.listen(3000,function(){
console.log("Express is running on port 3000");
});
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
HTML page for this application looks like below
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function() {
$('div').append("done !!! - ");
});
});
});
</script>
When I run http://localhost:3000/search in browser it gives me output with "name" from the database. But how can I see the index.html page and make it load on button click.
Update:
OP Asks:
"my question is not what code say....my question is how to change the
code so that expressjs works as RESTful API and not rendering engine"
In order to use express as a RESTful API here, you first need to serve up a static page.
Said another way, here are the steps:
1. Get your express server to serve up a static page.
2. Then get the button on that page to make a GET request to your api endpoint at /search (when clicked).
1 is explained in the 2nd part of my answer.
2 should already work, you just need to serve the page and click the button!
I explain why this doesn't work in the first part of my answer. You can't simply navigate to /search. I think that is what you mean by "not use it as a render engine".
Original Answer:
To understand what is happening here, it might be a good idea to look at how you're handling requests in your serverside code:
When I run http://localhost:3000/search in browser it gives me output with "name" from the database.
That code is:
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
This means that whenever a GET request goes to your route (in this case, the path /search on localhost:3000), the callback function executes. Essentially, when you access localhost:3000/search, your browser sends a GET request, Express checks* the request for a match with each route, and finally going "ok, that's the GET request I need to respond to, let's start searching!".
So it's behaving as expected. Of course, that is not what you want...
But how can I see the index.html page and make it load on button click
Try something like this:
app.get('/', function(req,res) {
res.sendfile('public/index.html');
});
It might not work as is, depending on where your html is defined and what you've named it. Remember to send the right file.
A simpler way to reason about this would be to let express know you're serving up static html.**
That could be done with
app.use("/", express.static(__dirname)); But again, make sure the html defined above is in a file in the proper root folder (probably named server or something similar), with the name index.html (and that there is only one of them).
(See the links on how express middleware works, and serving static HTML, at the bottom)
To wrap up, you implement the second half this answer first, so that you can go directly to localhost:3000 to load your index page. That page will have a button. Then, you'll be able to click the button and make a request to your /search route, without redirecting. The contents of name should come back to the browser now (instead of being served as a new page).
*More on how requests get checked/processed here.
**More info on serving static html. This blog on express fundamentals may also be useful.
1-You have to add routing for index.html
app.get("/index", function(req, res) {
res.render(index.html);
});
And then in your ajax code you can redirect to /index using window.location
2- you can directly render index.html.
Something like this
app.get("/search", function(req, res) {
res.render(search.html,{});
});
app.get('/index',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.render(index.html,{data:data});
});
});
then redirect to page on /index when clicking button.
The problem you have is that you are using Express as a render FrameWork. If you want to build an app with REST/API, the framework should not render the views or templates. The webpage navigation should be separate (e.g Angular JS). In your case, when you call /search you are actually only calling something in the server without any rendering instruction. That is why you see a response JSON object instead of your html template.
So, what to do?.. You need to make a navigation app on your client side, just navigating through templates with nothing out of normal, and program your button to do its request to some api url (something like: localhost:3000/api/search) and with the contents of the response do something: like filling a table, showing them somehow or whatever..
I recommend you to give a try to Angular JS. I am sure it can help you
Cheers
Here is the code I use when I am wanting to use a simple index.html page for test some front-end code.
app.get("/", function(req, res) {
res.sendFile( __dirname + '/index.html')
});
This will map the root path to your index.html. The __dirname assumes the index.html file is in the same directory as your initial server/app file for express. If you want to make it more generic you can do something like the following but then you will need to manually add the index.html to the address bar in your browser but it also lets you load any other static files you want.
app.get(/^(.+)$/, function(req, res){
res.sendFile( __dirname + req.params[0]);
});
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function(data) {
$('div').append(data);
});
});
});
</script>
you can read the documentation about $.ajax() from jquery api documentation
http://api.jquery.com/jQuery.ajax/
I am trying to learn Express with NodeJS and would like to render my views with plain HTML. I hacked together a webserver based on the Express API documentation and several Stack questions, particularly the answer by Andrew Homeyer in this question which states
You can have jade include a plain HTML page:
in views/index.jade
include plain.html in views/plain.html
... and app.js can still just render jade:
res.render(index)
My directory structure looks like this
Project
*web.js
Public
img
js
lib
gallerific
*jquery.opacityrollover.js
*jquery.gallerific.js
angular
theme
views
partials
*index.html
*index.jade
and my server looks like this.
var express = require('express'),
jade = require('jade');
var app = module.exports = express();
app.configure(function(){
app.set('views', __dirname + '/public/views');
app.use("/public/lib", express.static(__dirname + "/public/lib"));
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.set('view engine', 'jade')
app.use(express.bodyParser());
});
app.get('/', function(req, res) {
res.render('index');
});
app.get('/partials/:name', function(req, res){
var name = req.params.name;
res.render('/public/partials/' + name);
});
app.get('/public/data/:name', function(req, res){
var name = req.params.name;
res.json('/public/data/' + name)
});
app.listen(3000, function(){
console.log("Express app listening on port %d in %s mode", this.address().port, app.settings.env);
});
What I am seeing is that certain files fail to load from directories in which everything else loads just fine. For example, my Gallery page fails to load the jquery.gallerific.js javascript file from my lib/gallerific directory while it does load the jquery.opacityrollover.js. I have poked around with Chrome Developer Tools and see the following
I had this site working with the Angular Bootstrap webserver so it doesn't seem to be a javascript error with the client side code. Does anyone know what I might doing that would cause this problem?
The source is available at https://github.com/jamesamuir/express-simple-html.git
I figured it out. It turns out I had to resolve paths that I had forgotten about so that Express could render them correctly. It wasn't that the Gallerific javascript library didn't load, it was throwing an error on the image source of undefined for my gallery images (I am pulling them from a JSON file).
Once I put the appropriate paths in for the images and the data file, everything started working again. Thanks to everyone who provided a suggestion for me. It really helped me to work through the problem.