So I'm trying to make a web app, using a node server. I run into a problem where the CSS, Javascript don't work when linking them with a src like or .
The only way I can have css and javascript, is to directly put it inside the script and style parameters, but that doesn't seem that practical
The error that it pulls out shows a url:
127.0.0.1/home.js
why is this happening, and is there a work around?
here is the code
const fetch = require('node-fetch');
const fs = require("fs");
const http = require("http");
const url = require("url");
const server = http.createServer((req, res) => {
// get URL
const pathName = url.parse(req.url, true).pathname;
console.log(pathName);
// create split pathName
const pathSplit = pathName.split("/");
pathSplit.shift();
// HOME PATH
if(pathName === "/home" || pathName === "/"){
// Get HTML data
const data = renderHome();
res.writeHead(200, {"content-type": "text/html"});
fs.readFile(`${__dirname}/templates/template-basic.html`, "utf-8", (err, data) => {
fs.readFile(`${__dirname}/templates/template-battlepass.html`, "utf-8", (err, d) => {
let output = data.replace("{%CONTAINER%}", d);
res.end(output);
});
});
}
// ITEM SHOP PATH
else if(pathName === "/itemShop") {
// Get HTML data
const data = renderItemShop();
res.writeHead(200, {"content-type": "text/html"});
res.end("This is the item shop page");
}
// TOURNAMENTS PATH
else if(pathName === "/tournaments") {
// Get HTML data
const data = renderTournaments();
res.writeHead(200, {"content-type": "text/html"});
res.end("this is the tournaments page");
}
// ITEMS PATH
else if(pathSplit[0] === "items") {
// List all the items for the page
const itemsPages = ["backpacks", "contrails", "emotes", "gliders", "skins", "pickaxes", "wraps"];
let itemConfirm = false;
// If URL has been found, change itemConfirm to true
for(let i = 0; i < itemsPages.length; i++){
if(itemsPages[i] === pathSplit[1]){
// Get HTML data
const data = renderItems(pathSplit[1]);
res.writeHead(200, {"content-type": "text/html"});
res.end(`This is the page for ${pathSplit[1]} in items`);
itemConfirm = true;
}
};
// If itemConfirm is false, no url found
if(itemConfirm === false) {
res.writeHead(404, {"content-type": "text/html"});
res.end(`No URL found for ${pathSplit[1]} in items`);
};
}
// JAVASCRIPT
// NO URL FOUND PATH: 404
else{
res.writeHead(404, {"content-type": "text/html"});
res.end("could not find URL");
}
});
server.listen(1337, "127.0.0.1", () => {
console.log("listening for reqs now");
});
I created a simple server that can serve any type of file using the mime-types library. My basic http server works like this:
const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types'); //Creates the appropriate headerType based on the extension
http.createServer(function (request, response) {
let fileName = path.basename(request.url) || 'index.html' //so that the homepage uses index.html
filePathPart = path.dirname(request.url).slice(1) + "/" + fileName
filePath = "public/" + filePathPart //I store my files in public/js/ or public/css/
console.log(filePath) //just to check if I got the correct files
mimeType = mime.contentType(fileName)
getFile(response, mimeType, filePath)
}).listen(8080);
//I wrote a function to write all the responses the server gives, with this I don't need to expect a specific number of inputs, I can load any number of js/css files or even other html pages.
function getFile(response, mimeType, filePath) {
fs.readFile(filePath, function (err, contents) {
response.writeHead(200, { "Content-Type": mimeType });
response.end(contents);
})
}
Related
I've made a weather app using pure node js , but ultimately when i load the website, it only loads the HTML site and note the CSS.
Here is my index.js
const fs = require("fs");
const http = require("http");
var requests = require("requests");
const homeFile = fs.readFileSync('home.html', 'utf-8');
const replaceVal = (tempVal, orgVal) => {
let temperature = tempVal.replace("{%tempVal%}", orgVal.main.temp);
temperature = temperature.replace("{%minTemp%}", orgVal.main.temp_min);
temperature = temperature.replace("{%maxTemp%}", orgVal.main.temp_max);
temperature = temperature.replace("{%country%}", orgVal.sys.country);
return temperature;
}
const server = http.createServer((req, res) => {
if (req.url == '/') {
requests('https://api.openweathermap.org/data/2.5/weather?q=Pune&appid=0bfd89f4982a2d416a4ac5d299d03f9e&units=metric')
.on('data', function (chunk) {
const objData = JSON.parse(chunk);
const arr = [objData];
const realTimeData = arr.map(val => {
return replaceVal(homeFile, val);
}).join("");
res.write(realTimeData);
})
.on('end', function (err) {
if (err) return console.log('connection closed due to errors', err);
res.end();
});
}
});
server.listen(8000, "127.0.0.1");
Can anyone help in solving this issue.
It looks like you are only sending homeFile to your response for path "/". If you want to output your css as well you will need another path matching for any css files. That way when your html file asks the server for the css file it can request it.
if(req.url === "/"){
//send html here
}else if(req.url.match("\.css$")){
//send css here
}
I created a server without express and I'm trying to server a simple static webpage on localhost
here is my code :
const fs = require('fs')
const url = require('url');
const hostname = 'localhost'
const port = 3000;
const path = require ('path');
const http = require ('http')
const server = http.createServer((req, res) => {
if (req.url.match (/.css$/)) {
let cssPath = path.join (__dirname, req.url)
let cssReadStream = fs.createReadStream (cssPath, 'UTF-8')
res.statusCode = 200;
res.setHeader ("Content-Type", "text/css");
cssReadStream.pipe (res)
}
if (req.url === "/") {
fs.readFile("./index.html", 'UTF-8', (err, data) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
res.end(data);
})
}
if (req.url.match (/.jpg$/)) {
let jpgPath = path.join (req.url)
console.log (jpgPath)
let jpgReadStream = fs.createReadStream (jpgPath, 'UTF-8')
res.statusCode = 200;
res.setHeader ('Content-Type', 'image/jpg')
jpgReadStream.pipe (res)
}
})
server.listen (port, hostname, () => {
console.log ('server start')
})
first of all, it can display the HTML and CSS, however, localhost just keeps on loading after HTML and CSS displayed. Second of All, the image cannot be display (a instagram icon name icon.jpg).
the end result should look something like this:
I guess it has something to do with the favicon thing, but how do i fix it?
you need to use response.send() function which will be used to send the response back
const server = http.createServer((req, res) => {
if (req.url.match (/.css$/)) {
let cssPath = path.join (__dirname, req.url)
let cssReadStream = fs.createReadStream (cssPath, 'UTF-8')
res.statusCode = 200;
res.setHeader ("Content-Type", "text/css");
cssReadStream.pipe (res)
res.send("your data")
}
if (req.url === "/") {
fs.readFile("./index.html", 'UTF-8', (err, data) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
res.end(data);
res.send("your data")
})
}
if (req.url.match (/.jpg$/)) {
let jpgPath = path.join (req.url)
console.log (jpgPath)
let jpgReadStream = fs.createReadStream (jpgPath, 'UTF-8')
res.statusCode = 200;
res.setHeader ('Content-Type', 'image/jpg')
jpgReadStream.pipe (res)
res.send("your data")
}
})
I'm new in node.js and I'm implementing a Static file server.
what i'm trying to do is just get the file name from the url and display it. running the code id get this error:
_http_outgoing.js:489
throw new Error('Can\'t set headers after they are sent.');
Error: Can't set headers after they are sent.
this is my code
#!/usr/bin/env node
/*
* Basic node.js HTTP server
*/
const http = require('http');
const url = require('url');
const fs = require('fs');
const routes = Object.create(null);
function file(rew, res, serched) {
let fileSerched = serched[serched.length - 1]
fileSerched = __dirname + "/NodeStaticFiles/" + fileSerched;
fs.readFile(fileSerched, function(err, data) {
if (err) {
res.statusCode = 500;
res.end(`Error getting the file: ${err}.`);
} else {
res.setHeader('Content-type', 'text/plain');
res.writeHead(200)
res.end(data);
}
})
}
routes['file'] = file;
function onRequest(req, res) {
const pathname = url.parse(req.url).pathname
const uri = pathname.split('/', 3)[1]
let splittedPathname = pathname.split('/')
splittedPathname.shift()
splittedPathname.shift()
if (typeof routes[uri] === 'function') {
routes[uri](req, res, splittedPathname);
} else {
res.statusCode = 404;
res.end(`File not found!`);
}
res.end()
}
http.createServer(onRequest).listen(3000);
console.log('Server started at localhost:3000')
You need to make sure your code won't call something like res.end() more than once. For example:
function onRequest(req, res) {
const pathname = url.parse(req.url).pathname
const uri = pathname.split('/', 3)[1]
let splittedPathname = pathname.split('/')
splittedPathname.shift()
splittedPathname.shift()
if (typeof routes[uri] === 'function') {
routes[uri](req, res, splittedPathname);
} else {
// THIS WILL CALL res.end() and continue on
res.statusCode = 404;
res.end(`File not found!`);
}
// THIS WILL CALL res.end() AGAIN!!
res.end()
}
try adding a return after you call res.end() in an if/else
I wrote the server.js code below:
// Require modules
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
// Array of Mime Types
const mimeTypes = {
"html" : "text/html",
"jpeg" : "image/jpeg",
"jpg" : "image/jpeg",
"png" : "image/png",
"js" : "text/javascript",
"css" : "text/css"
};
// Create Server
const server = http.createServer(function(req, res){
const uri = url.parse(req.url).pathname;
const fileName = path.join(process.cwd(),unescape(uri));
console.log('Loading '+ uri);
const stats;
try{
stats = fs.lstatSync(filename);
} catch(e) {
res.writeHead(404, {'Content-type': 'text/plain'});
res.write('404 Not Found\n');
res.end();
return;
}
// Check if file/directory
if(stats.isFile()){
const mimeType = mimeTypes[path.extname(fileName).split(".").reverse()[0]];
res.writeHead(200, {'Content-type': mimeType});
const fileStream = fs.createReadStream(fileName);
fileStream.pipe(res);
} else if(stats.isDirectory()){
res.writeHead(302,{
'Location' : 'index.html'
});
res.end();
} else {
res.writeHead(500, {'Content-type' : 'text/plain'});
res.write('500 Internal Error\n');
res.end();
}
}).listen(3000);
I have an index.html page that simply says test and instead of rendering that in the browser I get a 404 Page Not Found. Since I tweaked the server.js file I believe the problem is there, but I am not quite sure.
Anybody see how this server code could have been written to better server the index.html file I have in the project?
Perhaps :
stats = fs.lstatSync(fileName);
and not :
stats = fs.lstatSync(filename);
You have the wrong variable/param... it's case sensitive.
I have made a server using javascript and Node.js that shows a JSON file in my browser.
However, I would like to call the site http://localhost:8888/Test.json without an extension.
For example just: http://localhost:8888/Test
Here is my server code:
var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;
file = (__dirname + '/Test.json');
http.createServer(function(req, res) {
var uri = url.parse(req.url).pathname, filename = path.join(process.cwd(), uri);
var contentTypesByExtension = {
'.html': "text/html",
'.css': "text/css",
'.js': "text/javascript",
'.json': "application/json" //Edited due to answer - Still no success :(
};
path.exists(filename, function(exists) {
if(!exists) {
res.writeHead(404, {"Content-Type": "text/plain"});
res.write("404 Not Found\n");
res.end();
return;
}
fs.readFile(file, 'utf8', function (err, file) {
if (err) {
console.log('Error: ' + err);
return;
}
file = JSON.parse(file);
console.dir(file);
var headers = {};
var contentType = contentTypesByExtension[path.extname(file)];
if (contentType) headers["Content-Type"] = contentType;
res.writeHead(200, headers);
res.write(JSON.stringify(file, 0 ,3));
res.write
res.end();
});
});
}).listen(parseInt(port, 10));
console.log("JSON parsing rest server running at\n => http://localhost:" +
port + "/\nPress CTRL + C to exit and leave");
How can I do that?
Should I use routes/express?
Does someone have any suggestions?
Thank you in advance!
Cheers, Vlad
Your problem is probably due to the content type. Having the extension .json is probably triggering your browser to consume it as application/json. So if you remove the extension you need to add the proper Content-Type.
Given that you are already playing around with content types, can't you just add it here, and make sure you write the type for jsons as well?
var contentTypesByExtension = {
'.html': "text/html",
'.css': "text/css",
'.js': "text/javascript",
'.json': "application/json" // <---
};
I've just used the sledgehammer method now with commenting this code fragment out:
if(!exists) {
res.writeHead(404, {"Content-Type": "text/plain"});
res.write("404 Not Found\n");
res.end();
return;
}
Now it works to call just: http://localhost:8888/Test
Cheers, Vlad