I have created my first node js application: a simple webserver.
Here's the code:
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
When I connect to the server via my browser I get the full string specified in my code as a web page.
Shouldn't the browser interpret that HTML code and display a link? Why do I get the full HTML code shown as plain text?
You have explicitly said that you are returning plain text, not HTML. The browser therefore treats it as plain text.
If you want HTML to be treated as HTML then say it is HTML:
{"Content-Type": "text/html"}
(Although you should send back an HTML document and not a fragment of HTML).
Following Code works for me:
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
You need to set the Headers. For more information check in Node API docs here.
Check the difference in your firebug or dev tools to understand how browser interprets differently based on Header Content-Type.
Related
When I serve an html file, having some javascript, from my nodejs web server I get different results, compared to when I include the same javascript from an external source. I have verified that directly opening the html file with the javascript inline or external source works the same, as expected.
In the example below I get "Modified header" in h1 tag, whereas with javascript as external source I get "Unmodofied header" in h1 tag.
Can somebody explain how to rectify the problem? Thanks.
Code for nodejs web server:
var http = require('http')
var fs = require('fs')
http.createServer(function (request, response) {
fs.readFile('htmlfile.html', function(err, data) {
response.writeHead(200, {'Content-Type': 'text'})
response.write(data)
response.end()
})
}).listen(8081)
htmlfile.html is as follows:
<html>
<body>
<h1 id = "header"> Unmodified header</h1>
<!-- <script src="populate_header.js"></script> -->
<script>
function populate_header () {
document.getElementById("header").innerHTML = "Modified header"
}
populate_header ()
</script>
</body>
</html>
In a nutshell, your http server is not configured to send populate_header.js to the browser when the browser asks for it.
When you do this in your HTML file:
<script src="populate_header.js"></script>
You're telling the browser to send your web server a request for a resource named populate_header.js. But your web server does not have a request handler that looks at what file is being requested and serve that specific resource. Your web server always sends htmlfile.html no matter what resource is being requested. So, the browser asks for a script file and gets an HTML file (causing it to basically just ignore it). Thus, your Javascript in populate_header.js is never delivered to the browser and thus the script in it never runs.
When you include the script inline, the Javascript is delivered with the HTML and works just fine without requiring another route on your web server.
A node.js web server serves NO files at all by default. It only serves files that you create a route handler for. It is possible to create a single route that will serve lots of static files (when using the Express framework, express.static() does exactly that). But, by default, it does not serve any files.
As soon as you need more than one route handler, I would recommend using a very simple framework like ExpressJS because it will save you a lot of time and is very lightweight. But, if you were going to add a new route handler to your existing little web server, you could do so like this:
var http = require('http')
var fs = require('fs')
http.createServer(function (request, response) {
if (request.method === "GET") {
let fname;
// Look at what resource was requested and match that up
// with the appropriate file name
// DO not accept any resource requested because that could open up
// your server for people to request your actual server code files
switch(request.url) {
case "/":
fname = "htmlfile.html";
break;
case "/populate_header.js":
fname = "populate_header.js";
break;
default:
break;
}
if (fname) {
fs.readFile(fname, function(err, data) {
if (err) {
response.writeHead(404);
response.end();
} else {
response.writeHead(200, {'Content-Type': 'text'})
response.write(data)
response.end();
}
});
} else {
response.writeHead(404);
response.end();
}
}
}).listen(8081)
Here, you can see you're looking at request.url to see what exactly was requested and then sending that resource. It's also looking a request.method to only respond to GET requests. And, it's sending 404 responses when some other file is sent.
This would all be a lot simpler using the ExpressJS framework.
const express = require('express');
const app = express();
// look for matching static resources in the static_files subdirectory
app.use(express.static("static_files"));
// send the htmlfile.html file when / is requested
app.get("/", function(req, res) {
res.sendFile("static_files/htmlfile.html");
});
app.listen(8081);
Then, just locate all your static resources in a sub-directory below your main server directory named static_files and the Express framework will automatically look in that sub-directory for files that match the requested URL. This code adds one custom route for / that specifically sends the htmlfile.html file, and you can certainly customize that however you want.
For further discussion of how node.js servers don't send any files by default, see these other related answers:
Can't load local files when using NodeJS server
Resources not loading in express
ajax request gives a 404 with express server (chrome) loads successfully with firefox without a server?
How to get files above the server directory in Node.js
I see when I want write a Node.js web application on my local machine, I don't need to set-up a local server using WAMP or MAMP. What is node.js really doing behind the scenes? I am providing this code to make a simple hello world web app:
var http = require("http");
http.createServer(function(request,response){
response.writeHead(200, {"content-type":"text/html"});
response.write("hello world");
response.end();
}).listen(8080);
console.log("server is running....");
When loading in my browser URL bar "localhost:8080" it works.
How this is working as and why don't I need a local server when working with Node.js?
You do have a local server... it's your Node.js application.
When you call http.createServer(), it creates an HTTP server. When you call .listen() on that server, it binds to the requested port, and optionally requested address, and listens for connections. When data comes in on those connections, it responds like any other HTTP server.
The HTTP server uses your request/response callback, firing it whenever a valid HTTP request comes in.
Because node comes out of the box with all the libraries you need to run a webserver, the http library that you are using is opening the 8080 port and handling the request with the function you provided
This part:
function(request,response){
response.writeHead(200, {"content-type":"text/html"});
response.write("hello world");
response.end();
}
No, you don't need it. Because node itself can be your webserver, just like in your example. Node is built on V8, which is chrome JavaScript engine .
Take a look a Express js module that gives you lots of features out of the box
I have a simple node.js server saved in a file called server.js, the code for which is below:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8010);
I am running this locally in command line (with node.js installed) by executing
node server.js
If I then access this in my browser (google chrome) with the URL my.local.IP.address:8010 it displays hello world successfully.
I am also creating a webpage that will execute this jQuery as soon as the page is loaded:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.get("http://my.local.IP.address:8010/", function(){
alert("Success");
}).fail(function(err){
alert("Failed");
alert(JSON.stringify(err));
});
});
</script>
When I open this html file in my browser it always creates an alert box saying failed followed by this stringified JSON object as the error (I've formatted it so it is easier to read):
{
"readyState": 0,
"status" : 0,
"statusText": "error"
}
This happens no matter how many times I've tried while the node.js server is running locally. I have also tried to make an async XMLHTTP request function that does it myself, and this does not work either.
I know both the jQuery and the XMLHTTP function I made work correctly since if I call the functions on the URL https://httpbin.org/get it will return successfully.
Any ideas as to where I have gone wrong?
It's a cross domain issue. Browser thinks your page is not part of http://localhost:8081 server. You need to change server code as follows in order to make it work.
http.createServer(function (req, res) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8010);
I guess it may be a cross domain issue, as you are using your IP address in the call, and localhost:8010 on the browser url to access your site. It is a problem common to ajax requests, and has nothing to do with Node.js
Try using the same url to access the site than the one you are targeting to.
See this similar issue with cross domain
I'm trying to create my first node.js server and I have some problems.
When I use
var http = require("http");
var server = http.createServer();
server.listen(8888);
No connection can be established to the server.
But when I use this
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
The server lands ok.
I used this in a file called server.js and runned the command node server.js. I'm using v 0.12.0
What am I missing? Why the server doesn't work on the first case?
The first block of code creates a server and listens on a port.
When you point a browser at it, the browser makes a request and then waits for a response.
You haven't told the server what to respond with, so it sits there doing nothing.
Eventually the browser times out.
In the second set of code, you've told the server how to respond to requests.
I am making a single web app that takes information from MYSQL database and displays it on screen using AngularJS and NodeJS. I have set up a node.js server that gives out JSON file from a database. It works fine if I connect to it like this: 192.168.1.57:8888 which is my home server ip or remote connecting my server and using localhost:8888. Doing this downloads the JSON file on my computer.
However. If I'm using javascript to get JSON file from the server it gives me this error:
GET http://localhost:8888/ net::ERR_CONNECTION_REFUSED
I have tried connecting to the server with both AngularJS and JQuery and they both give the same error. I've also tried 127.0.0.1 and that doesn't work either. What can I do to fix it or can I do this with a better alternative way?
This is the server code in node.js
var http = require("http");
mysql = require("mysql");
var connection = mysql.createConnection({
user: "test",
password: "test",
database: "test"
});
http.createServer(function (request, response) {
request.on('end', function () {
connection.query('SELECT * FROM feedback;', function (error, rows, fields) {
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
response.end(JSON.stringify(rows));
});
});
}).listen(8888);
this is the client side in angularJS:
(function(){
var app = angular.module('question', [ ]);
app.controller("ServerController", [ '$http', function($http){
$http.get("http://localhost:8888").success(function(data,status,headers,config){
console.log("success");
}).error(function(data,status,headers,config){
console.log("error");
});
} ]);
}
)();
Taking a guess at it, you're running into the Same Origin Policy, which requires that the page making the ajax request be in the same origin as the resource it's requesting (or that the server serving the resource supports CORS and allows the page's origin).
Two different ways this might be hitting you (I can't tell which, the question doesn't give enough information):
If the browser code is running in a page loaded from the file system, not via HTTP, then it's a cross-origin request because the protocols don't match (file: vs. http:).
If the page has not been loaded from localhost:8888, but instead from some other port on localhost, then the origins don't match because the port numbers are different.