Heads up: I am very new to Node.js, so this code might not be the best way to do it all. I am still in the learning process.
When I run the .JS file through node and go to the localhost:1337, all of the HTML shows up correctly, but the image does not render. when i look in the source code, the image is being brought in as Text/HTML and not an image.
Why is this? Is that why the image is not being displayed?
This is my code so far.
var http = require('http'),
fs = require('fs'),
request = require('request'),
url = require('url');
http.createServer(function (req, res)
{
console.log(req.url);
var request = url.parse(req.url, true),
action = request.pathname,
html = buildHtml(req);
res.writeHead(200, {'Content-Type': 'text/html','Content-Length': html.length,'Expires': new Date().toUTCString()});
res.end(html);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
function buildHtml(req)
{
var header = "",
body = '<img src="../Dilbert.jpg" alt="Dilbert">';
return '<!DOCTYPE html>'
+ '<html><header>' + header + '</header><body>' + body + '</body></html>';
};
var download = function(uri, filename, callback)
{
request.head(uri, function(err, res, body)
{
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('http://assets.amuniversal.com/145cd9c0fb4e0132ee37005056a9545d', 'Dilbert.jpg', function(){
console.log('done');
});
Related
I'm trying to Fetch a URL (http://localhost) that will return a picture (At this moment, the extension doesn't matter) through HTTP using Node.js.
Front End
let image = await fetch('http://localhost:3031', {
mode: 'cors',
method: 'GET'
})
Back End
var http = require('http');
var fs = require('fs');
http.createServer(function (req, res) {
res.setHeader('Content-Type', 'image/png');
fs.readFile('image.png', (err, data) => {
res.write(data, "binary");
res.end();
});
}).listen(3031)
I want to take that picture and then display it into the Website.
Im getting the file, NOT THE SRC
Directly in the HTML as:
<img id="loadedimage" src="http://localhost:3031/"/>
Or with fetch, using createObjectURL:
var element = document.getElementById('loadedimage');
var response = await fetch('http://localhost:3031');
var image = await response.blob();
element.src = URL.createObjectURL(image);
Working demo: https://codepen.io/bortao/pen/oNXpvYR
I'm trying out the code basics and want to write some basic client-server app.
I have an HTML page where user inputs two numbers (num1 and num2) then it passes to JS which passes it to HTTP server written with NodeJS. On the server the numbers should be added and returned to the HTML page. But the server returns this error:
ReferenceError: num1 is not defined
What is wrong with the code?
Here is the JS code:
function myFunction(num1, num2) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
num1 = Math.floor(num1);
num2 = Math.floor(num2);
document.getElementById("result").innerHTML = this.responseText;
}
};
xhttp.open("GET", "http://localhost:8080?num1=2&num2=3", true);
xhttp.send();
}
And here is the NodeJS code:
var http = require('http');
http.createServer(function (req, res) {
var resnum = 2 + req.params(num1) + req.params(num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(resnum);
res.end();
}).listen(8080);
You have to use the url module https://nodejs.org/api/http.html#http_message_url
var http = require('http');
var url = require('url');
http.createServer(function (req, res) {
var params = url.parse(req.url, true).query;
var resnum = 2 + params.num1 + params.num2; //or 2 + parseInt(params.num1) + parseInt(params.num2)
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(resnum);
res.end();
}).listen(8080);
If you want a concise code like yours you need to use some module like Express framework.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
const resnum = 2 + parseInt(req.query.num1) + parseInt(req.query.num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(resnum.toString())
})
app.listen(8080)
When you are using 'http' module only, the only thing you have to work with is req.url. You could try hard and get the parameters by breaking down the url but you would have a lengthy code:
var http = require('http');
http.createServer(function (req, res) {
const step1 = req.url.split('?')[1] //step1 = num1=2&num2=3
const step2 = step1.split('&') // step2 = [num1=2,num2=3]
let result = {};
step2.forEach((val) => { //break down strings further and put into result object
const value = val.split('=')
result[value[0]] = value[1]
})
var resnum = 2 + parseInt(result.num1) + parseInt(result.num2);
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(resnum.toString());
}).listen(8080);
Some notes:
You get that error because num1 is a variable argument to a
function. However we don't have a variable num1 declared.
Parameters come as strings so unless you parse them into integers,
you will have string concatenation and 223 as a result
res.write and res.end need a
string input so you need to parse back to string after calculations.
I'm new to node Js, I've build a really simple server that send me back a zip file I request. It's all working but after some request a crash occur and i visualize this message on the terminal :
FATAL ERROR: node::smalloc::Alloc(v8::Handle, size_t, v8::ExternalArrayType) Out Of Memory
var http = require('http');
var url = require('url');
var fs = require('fs');
var port = 1337;
// create http server
var server = http.createServer(function (request, response) {
var path = require('url').parse(request.url, true);
console.log('requested ' + path.pathname);
//get zipped resoures
if (path.pathname == '/getzip') {
console.log(request.url);
var queryData = url.parse(request.url, true).query;
if (queryData.name) {
var filename = queryData.name;
//open corrisponding file
var zipFile = fs.readFileSync('packets/' + filename);
response.writeHead(200, {
'Content-Type': 'application/x-zip',
'Content-disposition': 'attachment; filename=data.zip'
});
//send file in response
response.end(zipFile);
}
else {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('{error = "bad url"}');
}
}
}).listen(port);
server.timeout = 1000000;
Do you have any idea of what it can be? this code looks so simple.
Instead of reading the entire file into memory, you should leverage streams for this:
response.writeHead(200, {
'Content-Type' : 'application/x-zip',
'Content-disposition' : 'attachment; filename=data.zip'
});
fs.createReadStream('packets/' + filename).pipe(response);
I'm trying to make a cucumber test setup with Node.js that can test any website by using an iframe.
Normally the iframe is a no go because of cross script security limitations.
However if it was possible (I'm sure it is. And i trust you to come up with a solution)
to fetch the website being target for the test via the requested url when a specific url name is being requested, so that the iframe would be loaded with a copy of the test target.
Basically just a standard node.js server that fetches specific pages based on the req.url
Akin to an Address Request Router.
Here is my blatant attempt to do exactly that.
Fetching the test page via. the url works.
But i'm having a problem switching from the http server to the connection object.
Is there a way to "feed" the connection with the http server response?
PS. i also created a solution with two node.js servers.
Node 1 fetched the test target and mixing it with cucumber test page.
Node 2 hosting the cucumber test.
This solution is working. But it creates problems on websites where javascript naming conflicts occur. Which is why the iframe solution, that solves this problem by encapsulation is more appealing.
var http = require('http');
var connect = require('connect');
var port = process.env.PORT || 8788;
var server = http.createServer(function(req, webres)
{
var url = req.url;
console.log(url);
if(url == '/myWebsiteToBeTestedWithCucumberJS')
{
// Load the web site to be tested "myWebsiteToBeTestedWithCucumberJS"
// And update the references
// Finaly write the page with the webres
// The page will appear to be hosted locally
console.log('Loading myWebsiteToBeTestedWithCucumberJS');
webres.writeHead(200, {'content-type': 'text/html, level=1'});
var options =
{
host: 'www.myWebsiteToBeTestedWithCucumberJS.com,
port: 80,
path: '/'
};
var page = '';
var req = http.get(options, function(res)
{
console.log("Got response: " + res.statusCode);
res.on('data', function(chunk)
{
page = page + chunk;
});
res.on('end', function()
{
// Change relative paths to absolute (actual web location where images, javascript and stylesheets is placed)
page = page.replace(/ href="\/\//g , ' href="/');
page = page.replace(/ src="\//g , ' src="www.myWebsiteToBeTestedWithCucumberJS.com');
page = page.replace(/ data-src="\//g , ' data-src="www.myWebsiteToBeTestedWithCucumberJS.com');
page = page.replace(/ href="\//g , ' href="www.myWebsiteToBeTestedWithCucumberJS.com');
webres.write(page);
webres.end('');
});
});
}
else
{
// Load any file from localhost:8788
// This is where the cucumber.js project files are hosted
var dirserver = connect.createServer();
var browserify = require('browserify');
var cukeBundle = browserify({
mount: '/cucumber.js',
require: ['cucumber-html', './lib/cucumber', 'gherkin/lib/gherkin/lexer/en'],
ignore: ['./cucumber/cli', 'connect']
});
dirserver.use(connect.static(__dirname));
dirserver.use(cukeBundle);
dirserver.listen(port);
}
}).on('error', function(e)
{
console.log("Got error: " + e.message);
});
server.listen(port);
console.log('Accepting connections on port ' + port + '...');
Well it wasn't so difficult after all.
Being new to node.js i had to realize the possibilties of using multiple listeners.
Reading on nodejitsu's features helped me solve the problem.
Below example loads www.myWebsiteToBeTestedWithCucumberJS.com
when specifying the url as follows: http://localhost:9788/myWebsiteToBeTestedWithCucumberJS
where all other requests is handled as cucumber.js website requests.
Hope this make sense to other node.js newcucumbers.
var http = require('http');
var connect = require('connect');
var port = process.env.PORT || 9788;
var server = http.createServer(function(req, webres)
{
var url = req.url;
console.log(url);
if(url == '/myWebsiteToBeTestedWithCucumberJS')
{
loadMyWebsiteToBeTestedWithCucumberJS(req, webres);
}
else
{
loadLocal(req, webres, url);
}
}).on('error', function(e)
{
console.log("Got error: " + e.message);
});
server.listen(port);
console.log('Accepting connections on port ' + port + '...');
function loadMyWebsiteToBeTestedWithCucumberJS(req, webres)
{
console.log('Loading myWebsiteToBeTestedWithCucumberJS');
webres.writeHead(200, {'content-type': 'text/html, level=1'});
var options =
{
host: 'www.myWebsiteToBeTestedWithCucumberJS.com',
port: 80,
path: '/'
};
var page = '';
var req = http.get(options, function(res)
{
console.log("Got response: " + res.statusCode);
res.on('data', function(chunk)
{
page = page + chunk;
});
res.on('end', function()
{
page = page.replace(/ href="\/\//g , ' href="/');
page = page.replace(/ src="\//g , ' src="http://www.myWebsiteToBeTestedWithCucumberJS.com/');
page = page.replace(/ data-src="\//g , ' data-src="http://www.myWebsiteToBeTestedWithCucumberJS.com/');
page = page.replace(/ href="\//g , ' href="http://www.myWebsiteToBeTestedWithCucumberJS.com/');
webres.write(page);
webres.end('');
});
});
}
function loadLocal(req, webres, path)
{
console.log('Loading localhost');
webres.writeHead(200, {'content-type': 'text/html, level=1'});
var options =
{
host: 'localhost',
port: 9787,
path: path
};
var page = '';
var req = http.get(options, function(res)
{
console.log("Got response: " + res.statusCode);
res.on('data', function(chunk)
{
page = page + chunk;
});
res.on('end', function()
{
webres.write(page);
webres.end('');
});
});
}
// Cucumber site listening on port 9787
var dirserver = connect.createServer();
var browserify = require('browserify');
var cukeBundle = browserify(
{
mount: '/cucumber.js',
require: ['cucumber-html', './lib/cucumber', 'gherkin/lib/gherkin/lexer/en'],
ignore: ['./cucumber/cli', 'connect']
});
dirserver.use(connect.static(__dirname));
dirserver.use(cukeBundle);
dirserver.listen(9787);
var http = require('http');
// Create a server object
http.createServer(function (req, res) {
// http header
res.writeHead(200, {'Content-Type': 'text/html'});
var url = req.url;
if(url ==='/about') {
res.write(' Welcome to about us page');
res.end();
}
else if(url ==='/contact') {
res.write(' Welcome to contact us page');
res.end();
}
else {
res.write('Hello World!');
res.end();
}
}).listen(3000, function() {
// The server object listens on port 3000
console.log("server start at port 3000");
});
I have written a http server using node js
var sys = require("sys"),
http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs");
http.createServer(function(request, res) {
var parsed_url = url.parse(request.url);
var uri = parsed_url.pathname;
if(uri === "/test"){
res.writeHead(200, {'Content-Type': 'text/javascript'});
request.addListener('data', function (chunk) {
var data = eval("(" + chunk + ")");
console.log(data[0].id);
})
request.addListener('end', function() {
console.log('end triggered');
res.write("Post data");
res.end();
});
}
}).listen(8080);
and i am trying to send back response of ajax request but i am unable to receive any response. Here is the code for ajax request ,
var myhttp = new XMLHttpRequest();
var url = "http://localhost:8080/test";
var data = [{"a":"1"},{"b":"2"},{"c":"3"}];
var dataJson = JSON.stringify(data);
myhttp.open('POST', url, true);
myhttp.send(dataJson);
myhttp.onreadystatechange = function() {
if ((myhttp.readyState == 4) && (myhttp.status == 200)){
alert(myhttp.responseText);
}
else if ((myhttp.readyState == 4) && (myhttp.status != 200))
{
console.log("Error in Connection");
}
Can anyone help me what i am doing wrong ...
Thanks
Vinay
Your code is almost right but on your code sample you have
console.log(data[0].id)
the data object has no property id so if you only have
console.log(data[0])
there you have a response like
{ a: '1' }
therefore you can access the property a by doing
console.log(data[0].a);
UPDATED Updated with a full example
One more thing is that you are using eval and node comes with JSON.parse bundle with it so the snippet below is how i made it work
File: app.js
var sys = require("sys"),
http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs");
http.createServer(function(request, res) {
var parsed_url = url.parse(request.url);
var uri = parsed_url.pathname;
if(uri === "/test"){
res.writeHead(200, {'Content-Type': 'text/javascript'});
request.addListener('data', function (chunk) {
// removed this - eval("(" + chunk + ")");
var data = JSON.parse(chunk);
console.log(data[0].a);
})
request.addListener('end', function() {
console.log('end triggered');
res.write("Post data");
res.end();
});
} else if(uri === "/") {
fs.readFile("./index.html",function(err, data){
if(err) throw err;
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(data);
});
}
}).listen(8080);
On the same directory create a file index.html with the following:
<html>
<head>
<script type="text/javascript" charset="utf-8">
var myhttp = new XMLHttpRequest();
var url = "http://localhost:8080/test";
var data = [{"a":"1"},{"b":"2"},{"c":"3"}];
var dataJson = JSON.stringify(data);
myhttp.open('POST', url, true);
myhttp.send(dataJson);
myhttp.onreadystatechange = function() {
if ((myhttp.readyState == 4) && (myhttp.status == 200)){
alert(myhttp.responseText);
}
else if ((myhttp.readyState == 4) && (myhttp.status != 200))
{
console.log("Error in Connection");
}
}
</script>
</head>
<body>
</body>
</html>
That is a complete working example of what you want.
With regards to the same origin policy issues you were having is mainly due to the fact that you cant POST data between 2 different domains via ajax unless you use some tricks with iframes but that is another story.
Also i think is good for anyone to understand the backbone of a technology before moving into frameworks so fair play to you.
good luck
You have to read the data in a different way. Posted data arrives on a node server in chunks (the 'data' event), that have to be collected until the 'end' event fires. Inside this event, you are able to access your payload.
var body = '';
request.addListener('data', function (chunk) {
body += chunk;
});
request.addListener('end', function() {
console.log(body);
res.write('post data: ' + body);
});
Additionaly, there seem to be some issues with your client-side code (especially concerning the status-code checks), but i can't really help you with those as i always work with frameworks like jQuery to manage async requests.
If you want to build reliable node.js servers for web use, i highly recommend the high-performance HTTP-Framework Express. It takes away alot of the pain when developing a web-based server application in node and is maintained actively.