I started to work with node.js two days ago. I made my http server with node.js and I have a page which I made few month ago for some test purposes, but when I host my page on my computer it it works but without javascript files which are included in html page, like jQuery and some graph lib.
I tried to debug it with IE debugger, but I cannot solve that.
Funny thing is that when I open same page from my disk, just double clicking on .html file, it runs fine without any errors!
My question is what I supposed to do to make work? Did I miss something with node.js?
I have one html5 canvas element on page, and maybe that is a problem
This is my index.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello Dialog</title>
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta http-equiv="Cache-Control" content="no-store">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
<meta http-equiv="pragma" content="no-cache">
<link href="css/ui-lightness/jquery-ui-1.9.2.custom.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="RGraph.line.js"></script>
<script type="text/javascript" src="RGraph.common.core.js"></script>
<script type="text/javascript" src="RGraph.drawing.background.js"></script>
<script type="text/javascript" src="./js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="./js/jquery-ui-1.9.2.custom.min.js"> </script>
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="temperature(1).json"></script>
</head>
<body style="font-size: 10px;">
<button id="btn_hello">Say Hello</button>
<button id="btn_hello1">LUKA</button>
<button id="btn_hello2">ANJA</button>
<button id="btn_hello3">MARKO</button>
<div id="dlg_hello">Hello World!</div>
<canvas id="graph" width="600" height="500"></canvas>
<script>
var data = [];
var limit;
var Temp = [];
var TimeStamp = [];
function readTextFile(file, callback) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status == "200") {
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
readTextFile("temperature(1).json", function(text){
data = JSON.parse(text);
for(var i =0; i<Object.keys(data).length; i++)
{
//alert(parseFloat(data[i].TimeStamp));
TimeStamp[i] = data[i].TimeStamp;
Temp[i] = parseFloat(data[i].Value);
}
DrawGraph(Temp, TimeStamp);
});
function DrawGraph(data, timestamp)
{
var line = new RGraph.Line({
id: 'graph',
data: data,
options: {
labels: timestamp,
gutterLeft: 55,
gutterRight: 35,
gutterBottom: 35,
gutterTop: 35,
title: 'A basic line chart',
backgroundGridColor: '#aaa',
backgroundGridDashed: true,
textAccessible: true,
scaleZerostart: true,
labelsOffsety: 5
}
}).draw();
}
</script>
</body>
</html>
and this is server.js in node.js
var http = require("http");
var fs = require("fs");
var windows1250 = require("windows-1250");
var ht = fs.readFileSync('./index.html',"utf-8");
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html','Content-Length':ht.length});
res.write(ht);
res.end();
console.log(req.url);
}).listen(8888, function () {console.log("server is listening on port 8888");});
The server does not know where to find your javascript files. You might want to look into using express.js. This provides the capability to use the express.static command.
You are not hosting the files. The server doesn't know where to look for the JavaScript files, so it simply doesn't include them.
Look into using serve-static or a better solution to vanilla HTTP servers, express.
There is another similar answer here.
I remember in nodejs, you can read html like this:
var fs = require('fs');
fs.readFile('/path/html', 'utf8', function (err, data) {
if (err) {
console.log(err);
} else {
res.send(data);
}
});
if you want a better location path of the file, you can use
var path = require('path');
path.join(__dirname, '/path/html');
Then it will be like this:
var fs = require('fs');
var path = require('path');
var file = path.join(__dirname, '/path/html');
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
console.log(err);
} else {
res.send(data);
}
});
Related
I am trying to call index.html when someone enters localhost:3000/index.html, contact-me.html when someone enter localhost:3000/contact-me.html and 404.html when someone enters something else in node js project.
Please note i am not using express js module, just simply http, fs and url module
Below is the code snippet for the same.
index.js
var http = require('http');
var fs = require('fs');
var url = require('url');
//creating the server and listening on port 3000
http.createServer(function (req, res){
var path = url.parse(req.url, true);
var filename = "." + path.pathname;
console.log(filename);
fs.readFile(filename, function(err, data) {
if(err){
console.log("inside error");
fs.readFile('404.html', function(err, data){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write("Hello world");
return res.end();
});
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end();
});
}).listen(3000);
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>This is index html page</p>
</body>
</html>
contact-me.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>This is contact me page</p>
</body>
</html>
404.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>This is 404 error page</p>
</body>
</html>
but when i enter http://localhost:3000/blahblab.html its giving below error
_http_outgoing.js:670
throw new ERR_INVALID_ARG_TYPE('first argument',
^
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer. Received undefined
at write_ (_http_outgoing.js:670:11)
at ServerResponse.write (_http_outgoing.js:638:15)
at ReadFileContext.callback (C:\Users\jharo\Music\frontendMasters_beginners\odinproject\projectone\index.js:20:9)
at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:261:13) {
code: 'ERR_INVALID_ARG_TYPE'
}
I am currently serving my HTML page which references style.css and index.js, however, these files are not being applied to the HTML page even though I explicitly stated to include them if they are requested by 'req'?
My HTML (to show inclusions):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test site</title>
<link rel="stylesheet" href="/style.css" media="screen">
<script src="/index.js" charset="utf-8" defer></script>
.
.
.
My server.js code:
var PORT = 3000;
var http = require('http');
var fs = require('fs');
var path = require('path');
//cache the files
var index = fs.readFileSync('public/index.html', 'utf8', function read(err, data) {
if (err) {
throw err;
}
});
var style = fs.readFileSync('public/style.css', 'utf8', function read(err, data) {
if (err) {
throw err;
}
});
var indexJS = fs.readFileSync('public/index.js', 'utf8', function read(err, data) {
if (err) {
throw err;
}
});
function requestHandler(req, res){
res.setHeader('Content-Type', 'text/html');
res.statusCode = 200
res.write(index);
if(req.url === '/style.css'){
res.write(style);
}
if(req.url === '/index.js'){
res.write(indexJS);
}
res.end();
}
//use 3000 by default if PORT is not defined
if(!(typeof PORT !== 'undefined') || PORT === null){
http.createServer(requestHandler).listen(PORT);
}
else{
http.createServer(requestHandler).listen(3000);
}
Looks like you have the right idea but there are a couple things to note in the server code.
Setting the Content Type header tells the web browser how to interpret the file it is receiving. Your server code always sets it to 'text/html' where it should be set to 'text/css' for css, and 'text/javascript' for your js files.
res.write will append the file contents to the response. Since res.write(index) is being executed on every request, your HTML is being sent before the css/js within the same file. Try using a conditional for HTML like you are doing for CSS/JS like
if(req.url === '/') {
res.setHeader('Content-Type', 'text/html');
res.write(index);
}
Im trying to call a function from another js file that is located in the same application directory as my main js script and html file. I receive an error claiming that the referenced function does not exist. I have referenced both of the scripts in the main html file in the proper order but cant for the life of me figure out why it cannot detect the function. I can only assume it has something to do with how dojo parses through the files and have experimented with both its dojo/domReady! and dojo/ready modules in hopes to force scripts to load. I feel like this should be much simpler than Im making it out to be. Any help would be greatly appreciated.
html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Asset View</title>
<meta charset="utf-8">
<link rel="stylesheet" href="http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
<link rel="stylesheet" href= "styles/styles.css">
<script src="http://js.arcgis.com/3.14/"></script>
<script src="scripts/requests-js.js"></script>
<script src="scripts/layout-js.js"></script>
<script src="scripts/xmain-js.js"></script>
</head>
<body class = "claro">
</body>
</html>
requests-js.js
require(["dojo/dom","dojo/on","dojo/request","dojo/json","dojo/parser","dojo/ready"
], function(dom,on,request,JSON,parser,ready) {
ready(function() {
console.log("request start");
function sendRequest (url,assetCode,fromDate,toDate) {
console.log("Request innit");
request(url,{
method: "POST",
handleAs: "json",
headers: {"Content-Type": "application/json"},
data: JSON.stringify(
[
{
"AssetCodes": assetCode,
"FromGasDay": fromDate,
"ToGasDate": toDate
}
]
)
}).then(function(resp){
console.log(JSON.stringify(resp));
var naStorageJSON = resp;
});
}
console.log("request end");
});
});
main-js.js
require([
"dojo/dom","dojo/on","dojo/parser","dojo/json","dojo/request","dojo/ready"
], function(dom,on,parser,JSON,request,ready) {
ready(function() {
console.log("Main Start");
var url = "http://*********";
var assetCode = ["**"];
var toDate = "****";
var fromDate ="*****";
on(dom.byId("senecaLakeBtn"),"click", sendRequest(url,assetCode,toDate,fromDate));
console.log("Main End");
});
});
The issue is scope here. By declaring an empty array at the top of the js script (outside of its successive functions) the function can be accessible to other scripts in the application.
var app = [];
require(["dojo/dom","dojo/on","dojo/request","dojo/json","dojo/parser","dojo/ready"
], function(dom,on,request,JSON,parser,ready) {
ready(function(){
app.sendRequest = function sendRequest (url,assetCode,fromDate,toDate) {
...
...
}
}
it can them be called upon from other scripts by referencing
app.sendRequest(arg1,arg2,arg3);
I have the following HTML code in a file called test.html. Both the HTML file and the JSON file below are stored on a server within the same directory.
<!DOCTYPE html>
<html>
<head>
<title>Shape Up</title>
<meta name="robots" content="noindex,follow">
<meta name="description" content="">
<meta name="keywords" content="">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script language="JavaScript" type="text/javascript">
function ajax_get_json()
{
var hr = new XMLHttpRequest();
hr.open("GET", "game.json", true);
hr.setRequestHeader("Content-type", "application/json", true);
hr.onreadystatechange = function()
{
if(hr.readyState == 4 && hr.status == 200)
{
var data = JSON.parse(hr.responseText);
var results = document.getElementById("results");
results.innerHTML = "";
for(var obj in data)
{
results.innerHTML += data[obj].title;
}
}
}
hr.send(null);
results.innerHTML = "requesting...";
}
</script>
</head>
<body>
<div id="results"></div>
<script language="JavaScript" type="text/javascript">
ajax_get_json();
</script>
</body>
</html>
It pulls data from a file called game.json which is stored in the same directory.
{
"level_001":
{
"id":001,
"title":"Level 1",
"difficulty":0,
"comments":"this is how you complete level 1"
},
"level_002":
{
"id":002,
"title":"Level 2",
"difficulty":0,
"comments":"this is how you complete level 2"
}
}
The problem is that the results.innerHTML = ""; line is never reached. Why?
There are no errors in the browser, I've checked this on Firefox and on Safari.
According to jsonlint.com your JSON is invalid because of these properties:
"id":001
...
"id":002
You need to either remove the leading zeros:
"id":1
or make the numbers strings:
"id":"001"
For further details see the format rules spelled out at json.org
Presumably the line you mentioned is never reached because JSON.parse() gives an error about the above. (Do you not see an error in the browser's console?)
I am very new to node.js and I want to receive on an HTML5 website JSON from a PostgreSQL database. So, on the server side I use node-postgres module for DB connection and also express module for communication. The PostgreSQL query is returning a JSON object.
Server-side:
var express = require('express');
var app = express();
app.get('/data', function(req, res){
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/spots";
var client = new pg.Client(conString);
client.connect(function(err) {
if(err) {
res.send('could not connect to postgres');
}
client.query('SELECT * from spots_json where id=3276', function(err, result) {
if(err) {
res.send('error running query');
}
res.send(JSON.stringify(result.rows[0].json));
client.end();
});
});
});
app.listen(3000);
Client-side:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js" ></script>
<script>
$.get('http://localhost:3000/data',{}, function(data){
alert(JSON.parse(data));
},"json");
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
If I navigate to http://localhost:3000/data on the browser I get:
{\"type\":\"Point\",\"coordinates\":[-2.994783,43.389217]}
So I see that the server is sending the stringified JSON properly, but on the client I always get null data. I must have some misconception.
Ok this is how my code is so far, for anyone that could help:
serverside
var express = require('express');
var app = express();
app.get('/data', function(req, res){
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/spots";
var client = new pg.Client(conString);
client.connect(function(err) {
if(err) {
res.send('could not connect to postgres');
}
client.query('SELECT * from spots_json where id=3276', function(err, result) {
if(err) {
res.send('error running query');
}
res.set("Content-Type", 'text/javascript'); // i added this to avoid the "Resource interpreted as Script but transferred with MIME type text/html" message
res.send(JSON.stringify(result.rows[0].json));
client.end();
});
});
});
app.listen(3000);
clientside
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"></meta>
<meta charset="utf-8"></meta>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js" ></script>
<script>
$.get('http://localhost:3000/data?callback=?',{}, function(data){
alert(data.type);
},"json");
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
The client is now executed on http://localhost:8888/prueba/prueba.html
Im getting a js with the following Response:
"{\"type\":\"Point\",\"coordinates\":[-2.994783,43.389217]}"
The Response can be seen in the following screenshot:
https://www.dropbox.com/s/zi4c5pqnbctf548/pantallazo.png
But now the alert isn't even shown...
I think i need some light with this.
The data is already an object when you get it, not a string. So JSON.parse fails because you gave it an object when it was expecting a string. To verify, change
alert(JSON.parse(data));
to
alert(data.type);
and you should get "Point"
The reason you already have an object is because of the "json" parameter you provided to $.get. If you change that to "html" you will get a string back instead which you could then parse out into a JSON object.
I think you should not try to stringify your result when you put it in the response object.
Just put it entirely it will automaticaly that way :
res.set("Content-Type", 'application/json');
res.json(result.rows[0].json);
That is the right way to send information through REST APIs.
Then in your client side code, I don't know how it works but it should accept json natively.