Node JS/localhost server is not showing the image - javascript

I created localhost/server on node js, and my pictures/img tag doesn't work
<div class="text-center">
<img alt = "Bulb" src="pic_bulboff.gif" class="rounded" alt="bulboff">
</div>
but the problem is that they show up when I open them in a regular browser without the server
const http = require('http')
const fs = require('fs')
const port = 3000
const server = http.createServer(function(req, res){
res.writeHead(200, { 'Content-Type': 'text/html'})
fs.readFile('index.html', function(error, data) {
if(error) {
res.writeHead(404)
res.write('Error: File not Found')
} else {
res.write(data)
}
res.end();
})
})
above is the node server.
is there a problem that I can't really see?
Thanks!!!

By default a nodejs http server does not serve ANY files at all. You've created an http server that serves index.html for ALL incoming requests. So, a browser makes a request from your web server and you send it the HTML content from index.html.
Then, the browser parses that HTML and sees an <img> tag with a src attribute of "pic_bulboff.gif" so the browser then sends a request to your web server asking it for the content for /pick_bulboff.gif. But, you web server just responds to that request by sending index.html. That obviously doesn't work. You need your web server to know the difference between different path requests so it will server index.html when the browser is requesting /, but will serve that image when the browser is requesting /pick_bulboff.gif.
While most people will use a simple web framework that has the serving of static files as a built-in feature (like the Express framework), you can do it manually if you want:
const http = require('http');
const fs = require('fs');
const port = 3000;
function sendFile(fname, contentType) {
res.writeHead(200, { 'Content-Type': contentType});
fs.readFile(fname, function(error, data) {
if(error) {
res.writeHead(404);
res.write('Error: File not Found');
} else {
res.write(data);
}
res.end();
}
}
const server = http.createServer(function(req, res){
if (req.url === "/") {
sendFile('index.html', 'text/html');
} else if (req.url === '/pick_bulboff.gif') {
sendFile('pick_bulboff.gif', 'image/gif');
} else {
res.writeHead(404);
res.end('Error: Unsupported path');
}
});
server.listen(port);
In a more typical implementation, you would put all static files in one directory hierarchy that was separate from your code and you would use functionality similar to express.static() in the Express framework to serve any file in that static files directory that matches an incoming request so you don't have to create a custom route for every single static file you're using in your project.

Related

Node only sends html content to the client instead of sending a whole Vue app

I created a new vue project with the CLI and want to deploy it. Based on this documentation
https://router.vuejs.org/guide/essentials/history-mode.html#html5-history-mode
I added the history mode to the router. After running npm run build I took the example code for a static native Node server
https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
const http = require('http')
const fs = require('fs')
const httpPort = 3000
http.createServer((req, res) => {
fs.readFile('../base/index.html', 'utf-8', (err, content) => {
if (err) {
throw err;
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(httpPort, () => {
console.log('Server listening on: http://localhost:%s', httpPort)
})
So when navigating to localhost:3000 the vue project seems to load correctly
but I have a blank page with two errors
When I click on those js files it shows me the content of the index.html file. Obviously js is not able to understand this html content. How can I fix that problem?
Server will not send the whole vue app at once.
Browser get html file from server, when you browse to that url.
Browser parse the html file.
Browser detects assets (js, images, css).
Browser request those files.
It request those file from server, but you haven't initialized server to find those files.
So, need to add static files.
https://expressjs.com/en/starter/static-files.html
You can take reference from here
as #Sukul answer before, you just need to server the static files because you have now only one handler to server all the request coming with the HTML file (the mount point document) and when its requesting the *.js app it's expecting the valid javascript syntax instead it finds HTML, and that what the error messages are on the network tab
const http = require('http')
const fs = require('fs')
const nStatic = require('node-static');
var fileServer = new nStatic.Server('./public');
const httpPort = 3000
const controllers = (req,res)=>{
if(req.url.includes(".")
return fileServer.serve(req, res);
else
fs.readFile('../base/index.html', 'utf-8', (err, content) => {
if (err) {
throw err;
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}
}
http.createServer(controllers).listen(httpPort, () => {
console.log('Server listening on: http://localhost:%s', httpPort)
})
node-static ref
however, I highly recommend you trying to use express.js

Node.js serving HTML file doesn't find referenced files

I'm trying to make a simple game using Node.js and HTML. I want to be able to run the game locally (so localhost). But when I start my Node server, only the HTML content is rendered - my images don't show up and the JS is not loaded. I reference JavaScript files, CSS files and images in the HTML code. Not sure why the server cannot reference these from within the HTML.
Here is my server code:
const path = require('path')
const http = require('http')
var fs = require('fs')
//Set port number:
const port = 3000
const requestHandler = (request, response) => {
console.log(request.url)
response.writeHead(200, {"Content-Type": "text/html"});
response.end(fs.readFileSync('game.html'));
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log('Error: ', err);
}
console.log(`Game started\nGo to http://localhost:3000 to play\n`);
console.log(`Server is listening on ${port}...`);
})
Can anyone tell me how I can get my images/JS loaded?
TIA
You are not serving the static content correctly (i.e. images, CSS). Consider what happens when one navigates to http://localhost:3000/some_image.png - they will be served game.html!
You need to account for users requesting that content in your requestHandler by for example reading the file they want with fs.readFileSync(request.url). Remember to check that they can only request files you want them to be able to read!
You need static handlers to return static content. Check this
https://www.pabbly.com/tutorials/node-js-http-module-serving-static-files-html-css-images/.
Also, if your application is going to be huge then use some middle-ware like Express. (https://expressjs.com/)
If you use express framework, you can use static rendering:
app.use(express.static('public'));
where 'public' is the folder name

making js and other files available to html via node.js http server

I have a very simple web server like this:
var http = require('http');
var fs = require('fs');
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('something went wrong.');
return;
}
res.end(content);
});
}).listen(8080);
console.log("Server running on port 8080.")
This renders my index.html without any issues, but if I try to reference another file in my index.html via a script tag for instance, the site just gets stuck, unable to find the file which exists in the server directory.
How can I make those files available to my index.html file?
Please keep in mind that I realize this can be done much more easily with Express but I do not wish to use Express. I am trying to learn how things work behind the scene. Thanks in advance.
You need to make the directory visible to public. Its is recommend to use framework while developing the Node.js application.
Here is the code below to server file without framework.
var basePath = __dirname;
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var stream = fs.createReadStream(path.join(basePath, req.url));
stream.on('error', function() {
res.writeHead(404);
res.end();
});
stream.pipe(res);
}).listen(9999);
Refer : Node itself can serve static files without express or any other module..?

Running Node.js Server using User Level Root

Basic question but not sure where to turn to start figuring this out.
I've setup a very simple node server on port 3000 that just responds with an index.html file. When I call http://localhost:3000 in the browser, I get the proper page served up with dependencies. I don't want to authenticate every time though so I'd like to run it from the user-level.
I tried typing http://localhost~myusername:3000 in the browser but I keep getting:
The requested URL /~myusername:3000 was not found on this server.
(I have setup user-level root to be accessed through ~/Sites and have gotten access to files through here, even php, it's just when I start using a node server this problem occurs.)
How can I get node.js to respond to user-level requests? And it serve up the proper index.html from the relative path of the user-level root instead of /library/WebServer/Documents?
Update
Code of server.js:
var http = require('http');
var fs = require('fs');
function send404(response) {
response.writeHead(404, { 'Content-Type': 'text/plain' });
response.write('Error 404: Resource not found.');
response.end();
}
var server = http.createServer(function (req, res) {
if (req.method == 'GET' && req.url == '/') {
res.writeHead(200, { 'content-type': 'text/html' });
fs.createReadStream('./index.html').pipe(res);
}
else {
send404(res);
}
}).listen(3000);
console.log('server running on port 3000');

Linking css files to node.js server

So I have craeted a node.js server with two routes. I use the fs to get the html files from the views folder and then append them to the page. In those html files I have a normal link to the css file, which does not seem to work. Here is my node.js app:
var port = 1357;
var http = require('http'),
path = require('path'),
mime = require('mime'),
fs = require('fs');
var app = http.createServer( function(req, res) {
if (req.url === '/home') {
fs.readFile('views/index.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
}
else if (req.url === '/about') {
fs.readFile('views/about.html', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(page);
res.end();
});
}
else {
res.writeHead(301,
{Location: '/home'}
);
res.end();
}
});
app.listen(port);
console.log('Server running on port: ' + port)
In the html files I have:
<link rel="stylesheet" type="text/css" href="./styles/styles.css">
It does not work. In chrome's console I get "Resource interpreted as Stylesheet but transferred with MIME type text/html. "
You defined 2 routes: /home and /about. You also defined that anything apart from these two routes should default to an HTTP redirect to the /home route, and this is what causes the problem.
When the browser encounters the link to the css file, it requests the following URL: /styles/styles.css. the server receives this URL and since it doesn't match the two defined routes it will go into the else statement which will send a redirect to /home, so your browser, asking for a css file, will only receive the html page located in /home.
To fix this, you might need to add a new rule for your css file:
else if (req.url === '/styles/styles.css') {
fs.readFile('styles/styles.css', function(err, page) {
res.writeHead(200, {'Content-Type': 'text/css'});
res.write(page);
res.end();
});
}
Of course, if you have more css files you need to manage a specific folder instead of files. I suppose you're doing this to learn Node, because if you don't you might want to use express which is a Node ready to use web server that will save you lot of time.
When the client (the browser) asks the server for /styles/styles.css the server responds with 301 Moved Permanently and Location: '/home'.
The browser then asks for /home and gets an HTML document, which is not a stylesheet.
You have to give the browser the stylesheet when it asks for it.
static assets (as in your stylesheets) wont be served automatically. So what happens is that it falls through and lands at the 301 redirect to /home, where you serve text/html.
If you want to serve css that way, add a rule req.url==="/styles/styles.css"
Generally, I would recommend using a routing lib like express or koa. Or as minimum, connect. They make it easy to hook in features called middleware and enable you to make everything in a directory (like /public) serve static content with one rule.

Categories