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'm making a project where when the page opens, the pdf file is automatically downloaded, I managed to use this:
window.addEventListener('load', () => {
window.print();
})
but I want when windows opens the file is directly downloaded to the directory that I have defined, for example D: / myproject.
is there any way? I don't use pdf library because I make pdf with css myself.
thank you
window will not be accessible on server side code.
If you want to download file in browser, on just open the web page the you can use res.download() as follows:
app.get('/download', function(req, res){
const file = `${__dirname}/upload-folder/file_name.pdf`;
res.download(file); // Set disposition and send it.
});
As you want to download the file in a specific directory, so you can use the npm module
var download = require('download-file')
app.get('/download', function(req, res){
var url = ${__dirname} + "/upload-folder/file_name.pdf";
var options = {
directory: "path of directory/",
filename: "file_name.pdf"
}
download(url, options, function(err){
if (err) throw err
res.send("Done"); // Set disposition and send it.
})
});
Edit: To convert the html code into the pdf you can use the npm module jspdf
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 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.
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.