I'm trying to use just straight vanilla Node.js with no frameworks other than what is necessary for educational purposes. I currently have this setup:
var fs = require('fs'),
jade = require('jade');
function compile(dirPath, res) {
var filePath = __dirname + dirPath;
fs.readFile(filePath, 'utf8', function(err, fd) {
var fn = jade.compile(fd, { filename: filePath, pretty: true});
res.write(fn());
res.end();
});
}
exports.compile = compile;
Which is called when the requested page is asked for, like this:
var jadec = require('./jadecompile');
function start(res, postData) {
res.writeHead(200, {"Content-Type": "text/html"});
var cpage = '/staticpages/index.jade',
page = jadec.compile(cpage, res);
}
The page loads great and I get this as my view source:
<!DOCTYPE html>
<html>
<head>
<title>Hello!</title>
<link rel="text/css" href="assets/css/bootstrap.css">
</head>
<body>
<div class="hero-unit">
<p>Hello This Is A Test</p>
</div>
</body>
</html>
But the css doesn't work at all, I've been trying to google it but every answer seems to use express or something else, but I want to learn how to do this as vanilla as possible, so my question is, how can I handle the *.css so that the css is loaded properly, when I click on the href link in the view source, it loads my 404 page, rather than just the plain text of the css file. Thanks!
Feel free to view the repo at: https://github.com/Gacnt/Node-Tests
I managed to fix my problem by creating a function to handle static pages, such as .css or .js, like so:
var http = require('http'),
url = require('url'),
path = require('path');
fs = require('fs');
// ADDED THIS FUNCTION HERE -----------------------------------------------------
function handleStaticPages(pathName, res) {
var ext = path.extname(pathName);
switch(ext) {
case '.css':
res.writeHead(200, {"Content-Type": "text/css"});
fs.readFile('./' + pathName, 'utf8', function(err, fd) {
res.end(fd);
});
console.log('Routed for Cascading Style Sheet '+ pathName +' Successfully\n');
break;
case '.js':
res.writeHead(200, {"Content-Type": "text/javascript"});
fs.readFile('./' + pathName, 'utf8', function(err, fd) {
res.end(fd);
});
console.log('Routed for Javascript '+ pathName +' Successfully\n');
break;
}
}
// ADDED THIS FUNCTION HERE -----------------------------------------------------
function start(route, handle) {
function onRequest(req, res) {
var postData = "",
pathName = url.parse(req.url).pathname;
console.log('Request for ' + pathName + ' received.');
req.addListener('data', function(data) {
postData += data;
console.log('Received POST data chunk ' + postData + '.');
});
req.addListener('end', function() {
var pathext = path.extname(pathName);
if (pathext === '.js' || pathext === '.css') {
handleStaticPages(pathName, res);
} else {
console.log('--> Routing only the view page');
route(handle, pathName, res, postData);
}
});
}
http.createServer(onRequest).listen(4000);
console.log('Server is now listening at: http://127.0.0.1:4000 .');
}
exports.start = start;
In order to handle .css and other static files, there needs to be a file stream in place. Rather than using a switch statement you can just use the following.
var stream = fs.createReadStream(path); //create the file stream
stream.pipe(res); //transfer the file
Related
I'm trying to load an HTML page along with two separate CSS files through http.createServer()'s callback. Here's the important part of the code so far:
var server = http.createServer(function (req, res) {
var htmlData = fs.readFileSync(__dirname + "/public/index.html");
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(htmlData);
res.end();
}).listen(port);
When I try to load this, it also tries to load the CSS files linked within the HTML file. I've tried both adding direct links within the header and adding a script within the HTML file to add the links to the header, but neither work. How can I do this without putting the content of the CSS files directly within tags in the HTML file?
You are ignoring the request path and giving it the same file each time.
You need to serve the right file based on the request.
For example: if you want to serve two files index.html and style.css:
var server = http.createServer(function (req, res) {
if (req.url === '/' || req.url === '/index.html') { // respond to both / and /index.html
var htmlData = fs.readFileSync(__dirname + "/public/index.html");
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(htmlData);
res.end();
}
else if (req.url === '/style.css') { // respond to /style.css
var cssData = fs.readFileSync(__dirname + "/public/style.css");
res.writeHead(200, { 'Content-Type': 'text/css' });
res.write(cssData);
res.end();
}
}).listen(port);
I'm working on a small website, I'm a beginner in javascript and nodejs, I create a small server with nodejs but I do not know how to load my file.js in the server help please.
this is my server :
enter code here
let http = require('http');
let fs = require('fs');
let path = require('path');
http.createServer(function(req, res)
{
if(req.url === "/")
{
fs.readFile("index.html", "UTF-8", function(err, html)
{
res.writeHead(200, {"Content-Type": "text/html"});
res.end(html);
});
}else if(req.url.match("\.css$"))
{
var cssPath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(cssPath, "UTF-8");
res.writeHead(200, {"Content-Type": "text/css"});
fileStream.pipe(res);
}else if(req.url.match("\.png$")){
var imagePath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(imagePath);
res.writeHead(200, {"Content-Type": "images/png"});
fileStream.pipe(res);
}else if (req.url.match("\.jpg$")) {
var imagePath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(imagePath);
res.writeHead(200, {"Content-Type": "images/jpg"});
fileStream.pipe(res);
}
else
{
res.writeHead(404, {"Content-Type": "text/html"});
res.end("No Page Found");
}
}).listen(3000, '127.0.0.1');
and this is a part from my javascript file
$(function(){
let navMain=document.querySelector('nav');
let ul=document.getElementById('mainUl');
let li=document.createElement('li');
let a=document.createElement('a');
let login=document.createTextNode('Login');
$(window).on('scroll',function(){
const navMainTopMesure=navMain.offsetTop;
if($(window).scrollTop() && window.scrollY>=navMainTopMesure){
$('nav').addClass('fixed');
a.appendChild(login);
li.appendChild(a);
ul.appendChild(li);
a.addEventListener('click',function(){
document.querySelector('.login').style.display='flex';
});
return 0;
}else{
$('nav').removeClass('fixed');
ul.removeChild(li);
}
})
});
$(function(){
window.addEventListener('click',function(e){
if(e.target == document.querySelector('.register')){
document.querySelector('.register').style.display='none';
}
})
window.addEventListener('click',function(e){
if(e.target == document.querySelector('.login') ){
document.querySelector('.login').style.display='none';
}
})
let date =new Date();
document.getElementById('date').innerHTML=date.toDateString();
document.querySelector('.sign-up').addEventListener('click',function(){
document.querySelector('.register').style.display='flex';
})
document.querySelector('.closeRegister').addEventListener('click',function(){
document.querySelector('.register').style.display='none';
})
document.querySelector('.sign-in').addEventListener('click',function(){
document.querySelector('.login').style.display='flex';
})
document.querySelector('.closeLogin').addEventListener('click',function(){
document.querySelector('.login').style.display='none';
})
$('.mobile-nav').on('click',function(){
$('.nav-main ul').toggleClass('drop');
$('.mobile-nav i').toggleClass('fa-times');
})
});
function smoothScroll(target,duration)
{
var target = document.querySelector(target);
var targetposition = target.getBoundingClientRect().top;
var startposition = window.pageYOffset;
var distance = targetposition-startposition;
var starttime = null;
i just want to execute my function in javascripte file in my server.
my probleme when i execute the html file on the localhost in the browser evry think is okey but any javascript event happend
What you want to do is create a folder in your main app directory, called 'frontend' or 'src' or 'public' and in that folder create the directory that will be used by your index.html file. Throw your JS file in there wherever you want it.
In your main server or app.js file for node, do app.use(express.static(path.join(__dirname, 'whatevernameyouchoseforyourfrontendfiles')));
And after you serve the initial HTML files every time your server gets a request for a file it will know where to look.
I am following the guide in the Node Beginner Book and have managed to get all the way through to the last section, Handling file uploads. This book focuses on JavaScript calling methods and using request and response with very little HTML included only as strings when necessary.
All my console.log statements are showing me the correct file path. But instead of displaying the image I get the following HTML line:
I think the problem is in this line in requestHandlers.js:
response.write("<img src='/show' />");
It is supposed to be calling the show function at the bottom of requestHandlers.js. Look at the Console output at the bottom of this post and you can see that execution never gets into the show function. Source code and Console output is below:
index.js
var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");
var handle = {};
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
handle["/show"] = requestHandlers.show;
server.start(router.route, handle);
server.js
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
route(handle, pathname, response, request);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
router.js
function route(handle, pathname, response, request) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response, request);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
requestHandlers.js
var querystring = require("querystring"),
fs = require("fs"),
formidable = require("formidable");
var path = require('path');
var file = path.join(__dirname, 'tmp', "test.png");
function start(response) {
console.log("Request handler 'start' was called.");
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="file" name="upload" multiple="multiple"/>'+
'<input type="submit" value="Upload file"/>'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response, request) {
console.log("Request handler 'upload' was called.");
var form = new formidable.IncomingForm();
console.log("about to parse");
form.parse(request, function(error, fields, files) {
console.log("parsing done");
console.log("File = "+file);
fs.rename(files.upload.path, file, function (error) {
if(error) {
console.log("error");
fs.unlink(file);
console.log(file);
fs.rename(files.upload.path, file);
console.log(file);
}
});
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("received image:<br/>");
response.write("<img src='/show' />");
response.end();
});
}
function show(response) {
console.log("Request handler 'show' was called.");
response.writeHead(200, {"Content-Type": "image/png"});
fs.createReadStream(file).pipe(response);
}
exports.start = start;
exports.upload = upload;
exports.show = show;
Console output
C:\Users\pdl\Projects\TestSeparateJS>node index.js
Server has started.
Request for / received.
About to route a request for /
Request handler 'start' was called.
Request for /upload received.
About to route a request for /upload
Request handler 'upload' was called.
about to parse
parsing done
File = C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
error
C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
C:\Users\pdl\Projects\TestSeparateJS\tmp\test.png
You're sending the content as plaintext instead of HTML. So the browser never runs it as HTML. That's why you see the <img> text instead of an <img> tag being generated.
In your upload function change this:
response.writeHead(200, {"Content-Type": "text/plain"});
to this:
response.writeHead(200, {"Content-Type": "text/html"});
When using a newer version of node.js, you also might like to change the code files.upload.path into files.upload.filepath
<button type="submit" class="btn btn-success" onclick="on()">Force ON </button>
<script type="text/javascript">
function on(){req.url="/ledOn";}
</script>
This is my HTML button and i just need to route make it route to "ledOn" page in server.js file in order to perform some operations.
and this is the server.js file code.
var http = require('http');
var ejs = require('ejs');
var fs = require('fs');
var system = require('child_process').exec;
//var mraa = require('mraa');
var ledstatus = "off";
//var pin_2 = new mraa.Gpio(2);
//pin_2.dir(mraa.DIR_OUT);
http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('index.html', 'utf-8', function(err, content) {
if (err) {
res.end('error occurred');
return;
}
var temp = 'some temp';
console.log("Request: " + req.url);
if(req.url === "/ledOn") {
//pin.write(0);
ledstatus = "on";
console.log("pin 7 on");
}
if(req.url === "/ledOff") {
//pin.write(1);
ledstatus = "off";
console.log("pin 7 off");
}
var renderedHtml = ejs.render(content, {temp: temp, ledstatus:ledstatus});
res.end(renderedHtml);
});
}).listen(8080);
** i wanna add more buttons with more routes to my html page to use it controlling my galileo board, so any help would be appreciated **
I'm quite new to node and need some guidance and help. Before I go any further, I'm trying to do this without any other frameworks like Express. The situation is the following:
I've have a form where a user can upload a photo to a server running in node. The form has the following properties
<form action="/newImages/" method="post" enctype="multipart/form-data">
File goes : <input type="file" name="fileName"><br>
<input type="submit" value="Submit">
</form>
The form input is handled by this code
if (req.method == 'POST' && req.url == '/newImages/') {
console.log("Inside Post method");
var body = ''
req.on('data', function(data) {
body += data
})
req.on('end', function() {
var note = querystring.parse(body)
console.log(note)
fs.writeFile("./test.jpg",body, function(err){
if(err)
{
console.log(err);
}
else
{
console.log("The Picture was saved");
}
})
res.writeHead(302, {
'Content-Type':'text/plain',
'location':'/index.html'});
res.end('Found!');
})
}
However, something tells me I need to parse the data differently, as the output of this is unreadable. It looks like :
"\n\r\n����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0000��\u0000C\u0000\b\u0006\u0006\u0007\u0006\u0005\b\u0007\u0007\u0007\t\t\b\n\f\u0014\r\f\u000b\u000b"
Any ideas on how to get this to work? I should also note that I upload .jpg's only.
Thanks
I think that you are wrong when you save your picture. You don't need to use fs.writeFile() but fs.rename.
This cose works in my app.js:
app.post('/upload', function (req, res) {
var tempPath = req.files.file.path,
name = '',
targetPath = '';
fileExist = true;
fileNumber = 0;
var fileType = path.extname(req.files.file.name);
var fileName = path.basename(req.files.file.name,fileType);
while (fileExist) {
fileNumber_str = fileNumber.toString();
var current = fileName + "_" +fileNumber_str + fileType;
console.log("Controllo per "+current);
if (fs.existsSync(__dirname + "/images/orig/" + current)) {
console.log("--> Esiste");
fileNumber++;
} else {
var newPath = __dirname + "/images/orig/" + current;
console.log("nuovo nome : "+newPath);
fs.rename(tempPath, newPath, function(err) {
if (err) throw err;
//Ora creo il thumb
console.log("Upload completed!");
});
break;
}
}
res.redirect("/");
res.end();
});
Take a look.
M.
It seems that you cannot parse multipart data with querystring.parse.
You have to write your own parser or use third-party module, like node-multiparty.
With multiparty module the code will be like this:
if (req.method == 'POST' && req.url == '/newImages/') {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var tmp = files.fileName[0].path;
fs.rename(tmp, '/your/dir/img.jpg', function(err) {
if (err) throw err;
console.log('success');
});
res.end('Found!');
});
}