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');
Related
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.
I'm new to web design and am trying to create and a simple local server and a local client. I fear I have fallen down the rabbit hole as I'm going round in circles.
I have made a simple Express node.js server:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
var port = 3000;
app.listen(port, function() {
console.log("Listening on port: " + port);
});
app.get('/', function(req, res) {
console.log(req);
res.send('Get request received at "/"');
});
app.post('/quotes', function(req, res) {
console.log(req);
// do something
});
and I have a javascript client:
const url = "http://localhost/3000";
fetch(url)
.then((resp) => resp.json())
.then(function(response) {
let data = response.results;
console.log(data);
//do something
})
.catch(function(error) {
console.log(JSON.stringify(error));
});
called from an index.html file.
When I type http://localhost:3000 into my (chrome) browser I get
'Get request received at "/"'
displayed in the browser and a very long req displayed in the node.js console just as I expect.
However when I load the index.html into the browser it doesn't work.
Originally the index.html file was in a different directory to the node.js server and I got the error:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
So I moved it into the same directory as the node.js server and now get this error:
Failed to load resource: net::ERR_CONNECTION_REFUSED
in the browser console and no output in the node console.
Seems I needed to enable cors on my server. npm install cors and this answer solved my problem.
How to allow CORS?
I would replace
const url = "http://localhost/3000";
with const url = "http://localhost:3000";
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..?
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.
I just started using node js and I've moved one of my websites on it:
var http = require('http');
var fs = require('fs');
var app = http.createServer(function (req, res) {
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
});
app.listen(8080);
The index.html is my website home page. With only html it works, but if i put tags in it (for including jquery for example), it gives JS errors in firebug : Uncaught syntax error : unexpected token < in jquery.js, and then of course '$ is undefined'.
It doesn't load images either.
I don't really need to do some routing or use Express framework or anything, it's just a simple one-page website.
What am I doing wrong ?
Your server isn't handling requests for images or other resources. All requests are given the same response of the ./index.html page.
This means that if an external script or an image is included in the page, when a request is made by the browser for those resources, the original index.html page will be delivered instead.
NodeJS is fairly low-level. You need to set up your server to manually handle requests for different types of resources based on the URL for each request.
Your best bet will be to read through some NodeJS tutorials. They should cover the basics of serving content, though many of them won't deal with the lower-level details, and will suggest packages like Connect or Express.
Change your code to this, and you'll see all the resources being requested.
var http = require('http');
var fs = require('fs');
var url = require('url');
var path = require('path');
var app = http.createServer(function (req, res) {
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname).toLowerCase();
console.log(pathname);
if (ext === ".html") {
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
}
});
app.listen(8080);