I have created a server with Node.JS express where I open html file in public folder.
app.use(express.static(__dirname + '/public'));
app.listen(8080);
I have done this before without any problems. But in this project when I try to open the server in 127.0.0.1:8080 it automatically downloads the index.html file. I tried it with different browsers but result was same.
UPDATE
I could open html file in Edge. But it was very very slow like it is processing some thing. And it got stuck when I send a request to the server.
I tried opening the HTML file separately with the browser it works without any problem.
And tried giving another html file location, result was same.
I do not know what is the exact problem here. But I got to know that it has to do something with content type as td-lambda mentioned in the comments. So I found a solution like this.
var express = require('express');
var app = express();
var server = app.listen(8080);
app.set({
'Content-Type': 'text/html'
});
app.use(express.static(__dirname + '/public'));
And this solved my problem.
Related
I am trying to use Socket.IO in my web application and it has worked great so far. However, I have been trying to fix one specific issue for a long time and have not been able to find anyone else having the same issue. Socket.IO works great on URLs where it is just site.com/example, however, when I stack paths on the domain, I get a 404 in socket.IO. For example, site.com/user/example displays a 404 for socket.IO. In the log, it tries to access socket.IO at site.com/user/socket.io/... when it needs to access it at site.com/socket.io. It seems to only replace the url after the last / so site.com/ex/a would make it try to get socket.io at site.come/ex/socket.io.(I am using ExpressJS, I didn't know if that was relevant.)
I have tried to set the path and resource for socket.io to use in the client script. Also, I included the path when binding the socket.io instance to the http server.
Here is my server side code.
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server, {path: '/socket.io'});
Here is my client side code.
var socket = io.connect('https://example.net', {
path: '/socket.io',
resource: '/socket.io',
transports: ['websocket'],
upgrade: false
})
Thanks so much for all help!
(I am sorry for any incorrect formatting of this question, this is my fist time asking on StackOverflow!)
You likely need a leading slash on the socket.io script tag.
The big clue is when you said your socket.io script loads when the page URL is https://example.net/dashboard, but doesn't load when it's https://example.net/user/fludo. And, the screen shot shows it trying to load the script from https://example.net/user/fludo/socket.io/socket.io.js which is, indeed, the wrong path.
The problem is that your <script> tag is using a page relative link with no leading / on the URL. That means the browser will combine the path of the page URL with the filename in your <script> tag. But, you don't want to use the path of the page. You want to load it from the same place every time. So, to do that, you change from this:
<script src="socket.io/socket.io.js"></script>
to this:
<script src="/socket.io/socket.io.js"></script>
I have already added the codes for serving an image on my node server but it seems to not serve images in the HTML when connecting to Node. I have also external CSS and JS that are being served correctly. Here is the fragment of my code in Node (See below). Thank you in advance!
var server = http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname);
var handler = handlers[req.url];
if(ext) {
if(ext === ".css"){
res.writeHead(200, { "Content-Type" : "text/css" });
}
else if(ext === ".js") {
res.writeHead(200, { "Content-Type" : "text/javascript" });
}
else if(ext === ".jpg") {
res.writeHead(200, { "Content-Type" : "image/jpg" });
}
res.write(fs.readFileSync(__dirname + pathname, "utf8"));
res.end();
}
else if(handler) {
handler(req, res);
}
else {
res.writeHead(404, { "Content-type" : "text/plain" });
res.end();
}
});
server.listen(80);
I've seen a lot of questions like this on Stack Overflow when someone tries to implement their own static file server instead of using Express or something that works, and fails to make it work. If you can implement your own static file server then do it. If you can't, then it should be a sign that maybe it's not a good idea. Update: See below for solutions without Express.
Problems
Just by glancing at your code code I already see several serious problems with it, including:
Your code is insecure - it allows anyone to get any file on your system.
Your code is blocking - it will grind to a halt as soon as you get any concurrent connections.
Your code doesn't work for binary files - only for text files, and only those with UTF-8 encoding
Your code doesn't work for uppercase filenames, .jpeg extension etc.
Your code doesn't serve HTML files correctly
Your code crashes when files don't exist instead of responding with proper code
Solution
Anyone who answers a question like this has two options: either put a lot of effort and time into fixing every one of the problems mentioned above (which rarely happens because it is not a trivial task and that's why all you see are comments mentioning one or two of those problems instead of answers) or you can explain how the task should be done properly instead of adding countless fixes to something that was not a good idea in the first place.
That having been said, what you can do to achieve your goal here in a secure and performant way is to put your static files (HTML, CSS, images etc.) into a directory, e.g. called html and use Express (or some other frameworks, see below) with a simple code like this:
var path = require('path');
var express = require('express');
var app = express();
var htmlPath = path.join(__dirname, 'html');
app.use(express.static(htmlPath));
var server = app.listen(80, function () {
console.log('listening on port', server.address().port);
});
See the full example with explanation on GitHub:
https://github.com/rsp/node-express-static-example
I put this example on GitHub because there are a lot of questions on Stack Overflow related to problems that people have with serving static files in Node. It's open-source, you can adapt it to your own needs and use in your code.
For more info on Express, see:
http://expressjs.com/en/4x/api.html
Other options
Other frameworks that you can use to serve static files include:
koa, Restify, Hapi, Sails, LoopBack and more.
Without a framework
If you still think that you don't want to use a high-level framework that does the job correctly and you want to roll your own solution, maybe for educational purposes, then see this answer:
How to serve an image using nodejs
It explains how to serve static images with:
express.static (express built-in middleware, like in this answer)
express (express but without express.static)
connect (one level below than express)
http (using Node's http module)
net (not even using http module)
All of the examples posted are tested and work on Node versions 4, 5, 6 and 7.
Other related answers:
How to serve an image using nodejs
Failed to load resource from same directory when redirecting Javascript
onload js call not working with node
Sending whole folder content to client with express
Loading partials fails on the server JS
I want to write my HTML in HTML. Not some fancy way. The only thing that would be cool is to be able to use some sort of include statement to include header/navigation/footer for each page.
I've looked at pug, ejs, mustache, nunchuck, etc etc. I hate all of these things. I just want to write HTML..
What is a simple node module to do this? And how do I set up the render engine in my main app.js? I am using express
You can just set up your express routes to connect with html pages. Here's a simple example:
var express = require('express');
// Create express app
var app = express();
// Route index page to an index html page
app.get('/', function(req, res){
res.sendFile(__dirname + '/path/to/views/index.html');
});
// Create server
app.listen(8080, function(){
console.log('Ready on port 8080...');
});
As a side note, ejs is basically html but with some bonus functionality. You can totally get away with writing only html in ejs pages and then start using the ejs features when you get comfortable with it.
Looks like you want to server only static html files using node not some jsp equivalent dynamically generated html.
Express has support for serving static files and you do not need to define any routes for that!
http://expressjs.com/en/starter/static-files.html
Second thing I understood from your post is you want to include some common html to your html page. One way of doing that is to use a browser/client side java script framework. Take a look at angular.js. It has ng-include. Basically you can include one html file to another using that.
i'm reading the book 'Node.js for PHP Developers'. I have created a NodeJS Web Server and it receives requests and gives response too. But whenever I access a PHP file to reroute it to a JS file (requirement it is), my browser automatically downloads the PHP file.
Here's my JS code, according to which it also downloads JS files(e.g. when I access localhost:1337/first.njs)
var http = require('http');
var url = require('url');
var file = require('./first.njs');
http.createServer(function(req, res) {
if(url.parse(req.url).pathname == 'first.php')
file.serve(req, res);
else
res.end('The file doesn\'t exist');
}).listen(1337, '127.0.0.1');
console.log('Server is running on 1337');
And here's my PHP file if it matters
<?php
echo "ASD";
?>
I know it feels like a really dumb question, but I can't figure out why that happens.
Browsers tested: Chrome and Firefox.
UPDATE
Couldn't figure out the exact problem neither could replicate the problem - but this is my latest code if anyone wants to reroute a requested PHP file to a JS file and serve it(the JS file)
var http = require('http');
var url = require('url');
var file = require('./first.njs');
http.createServer(function(req, res) {
if(url.parse(req.url).pathname == '/first.php')
file.serve(req, res);
else
res.end('File not found');
}).listen(1337, '127.0.0.1');
console.log('Server is running on 1337');
If you want to check if a PHP page can be rendered without actually rendering it to the page you can use an ajax request in JavaScript/jQuery.
$.ajax({
type: "POST",
url: 'YOUR PHP FILE PATH',
success: function (dataCheck) {
// file was accessed
}
});
Inside your success function you can output that the PHP file was successfully accessed.
Once you get a better handle on node, you'll probably want to use expressjs, take a look at expressjs routing.
app.get('/first.php', function(req, res){
res.send('You accessed first.php!');
});
If you then wanted to display the php, you could use php-node to render php in node.js.
It seems that you don't have Apache (or some other server) or PHP configured. The request has to go to the PHP script first. So you would have to hit localhost:80/file.php and then in the PHP script redirect to localhost:1337/file.js.
A better suggestion for what you want to do is actually reverse proxy from Apache to Node.js and then have Node.js read the path.
I've got a very simple html5 game on one side. Opening the game's html file directly with my browser makes the game work just fine. On the other side, I have an html sever made with node.js that can serve html text normally (tags like < /br> < p> and so on).
But when I tell the server to display my game as html text priting the whole html file, the canvas fails to render (although the title does). So now I'm kind of lost on what's happening and why I'm not able to link those two things together. Here's a simplified version of my server's code:
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(index);
res.end()
}).listen(7777);
So, what am I doing wrong here? Should this work normally? Am I missing something?
It seems just as if the javascript was sent as plain text and the code was never actually executed.
Your server serves only the index.html so if that page depends on any other resources it will fail to work as requests to CSS and JS files will fail. Try out e.g. this:
$ npm -g install simplehttpserver
$ simplehttpserver /path/to/your/folder
Then go with browser to
http://localhost:8000/index.html