Why does node.js display same content multiple times? - javascript

I have a code that displays HTML document (which includes .jpg image) and a code that creates a new .txt files, saves data into it and displays it in console.
But everytime i run this code with google chrome, the data gets displayed 3 times...
Code
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function (request, response) {
//branje HTML datoteke
var file_path = '.' + request.url;
if (file_path == './')
file_path = './func.html';
var extname = path.extname(file_path);
var contentType = 'text/html';
switch (extname) {
case '.jpg':
contentType = 'image/jpg';
break;
}
fs.readFile(file_path, function (error, content) {
if (error) {
if (error.code == 'ENOENT') {
fs.readFile('./404.html', function (error, content) {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
}
else {
response.writeHead(500);
response.end('Server error!: ' + error.code + ' ..\n');
response.end();
}
}
else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
fs.writeFile("external-data.txt", "- TEXTFILE-CONTENT\n", function (err) {
if (err) {
return console.log(err);
}
console.log("Data saved!\n");
});
fs.readFile(__dirname + '//external-data.txt', function (err, data) {
console.log(data.toString());
response.end(data);
});
Result
Any suggestions? What's wrong with the code, why does it display same text multiple times instead of once? Thank you!

Open the developer tools in Chrome. Look at the Network tab. Make the request.
You will see Chrome make multiple requests. For example, for /favicon.ico.
Each request triggers your code.

Related

How to load an html file with <script> tag on a node js server?

I have an html file that has some javascript on script tag. I created a server with node js but when I try to load the website on the server I only get to see the html part of the file, and not the javascript part.
Here's a part of the code in html on the head tags that I tried to link it with javascript:
<head>
<title>HTML5 Canvas Winning Wheel</title>
<link rel="stylesheet" href="main.css" type="text/css" />
<script type="text/javascript" src="Winwheel.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="app.js" type="text/javascript"></script>
</head>
And here is the app.js where I created the server:
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response) {
var path = url.parse(request.url).pathname;
switch (path) {
case '/index.html':
fs.readFile(__dirname + path, function(error, data) {
if (error) {
response.writeHead(404);
response.write(error);
response.end();
} else {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write(data);
response.end();
}
});
break;
case '/Page2.html':
fs.readFile(__dirname + path, function(error, data) {
if (error) {
response.writeHead(404);
response.write(error);
response.end();
} else {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write(data);
response.end();
}
});
break;
default:
response.writeHead(404);
response.write("opps this doesn't exist - 404");
response.end();
break;
}
});
server.listen(8082);
When you serve index.html client will try to get all resources specified in index.html from your server. You can see that if you log path variable in your callback function:
/index.html
/main.css
/Winwheel.js
/app.js
What you can do here is to make more switch cases for other files like main.css and app.js but this can get overwhelming if you have many files to serve.
Instead, take a look at how to serve static files from your server here:
https://expressjs.com/en/starter/static-files.html or how to create simple express server here https://expressjs.com/en/starter/hello-world.html.
If you don't won't to use express you can remove switch statement and do something like this:
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(request, response) {
var path = url.parse(request.url).pathname;
fs.readFile(__dirname + path, function(error, data) {
if (error) {
response.writeHead(404);
response.write('This page does not exist');
response.end();
} else {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write(data);
response.end();
}
});
});
server.listen(8082);

How to make my server fetch js file instead of fetching html again?

I have an index.html which uses bundle.js file. It works fine in the local machine. But when try to do the same thing with server, it just shows only html file content. when looked at the code in console instead of regular js code the bundle.js file contains same html code. This the server code I have used.
var http = require('http');
var fs = require('fs');
const PORT=3012;
fs.readFile('./index.html', function (err, html) {
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(PORT);
});
In order to serve your bundle.js file and another files without using express or another already made tested and preferred way, you can serve any file you like (see "routeToFile" function).
//Return the file path you want to serve to that request url
const routeToFile = ({url}) => {
if(url === '/'){
return './index.html';
}
return `.${url}`;
}
With "mimeTypes" array you can guess the right mime type by just checking the file extension (mimeTypes[fileExtension]).
//File mime types for content type response
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg'
};
If there is an error, for instance if the file don't exist, just send the error code, or a page you like too (see "onError" function)
//If the file is missing or there is an error
const onError = (error, response) => {
if(error.code == 'ENOENT') {
response.writeHead(404);
}
else {
response.writeHead(500);
console.error(error);
}
response.end();
}
Finally, the main function to run all of this, will be:
//Create the http server
http.createServer((req, res) => {
const filePath = routeToFile(req)
const fileExtension = String(path.extname(filePath)).toLowerCase();
const contentType = mimeTypes[fileExtension] || 'application/octet-stream';
fs.readFile(filePath, function(error, content) {
if (error) {
return onError(error, res)
}
else {
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
}
});
}).listen(PORT, () =>{
console.log(`server start at port ${PORT}`);
});
Don't forget the requires, or it won't run :D
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3012

Upload image using Node js and electron. (convert from c# code)

I'm converting an application from c# to electron and i have some problems when i try to make a request to upload an image on a server (not my server).
For c# i used RestSharp library and all worked fine.
private void UploadImage(string id)
{
RestClient client = new RestClient("https://www.website.com")
{
CookieContainer = new CookieContainer()
};
string path = #"D:\Downloads\image.jpg";
var request = new RestRequest("/upload?id=" + id, Method.POST);
request.AddFile("myfile", File.ReadAllBytes(path), Path.GetFileName(path), "image/jpeg");
request.AddHeader("Content-type", "application/json");
request.AddHeader("Accept", "application/json");
request.RequestFormat = DataFormat.Json;
client.Execute(request);
}
How can i convert this code in Node js? The only thing i could found was code that uploaded to their own server and that does not work for me.
This is what i tried in Node js
var fs = require('fs');
var request = require('request');
fs.createReadStream("D:\Downloads\image.jpg").pipe(request.post("https://www.website.com/upload?id=" + productId, function (error, response, body) {
if (error) {
console.log(error);
} else {
console.log(response);
}
}));
Using the code above i get status code 200 and the body response is telling me that no image was select. So the request is working, but sending the image doesn't.
This is what i did in order to solve the problem. Maybe it will help somebody else too.
var fs = require('fs');
var request = require('request');
var req = request.post(uploadURL, function (err, resp, body) {
if (err) {
console.log('Error!');
} else {
console.log('URL: ' + body);
}
});
var form = req.form();
form.append('myfile', fs.createReadStream("path\to\image.jpg"), {
filename: "image.jpg",
contentType: 'image/jpeg'
});
I've been trying to use the same technique using Electron to upload files to my localhost test server, but no luck. My code returns as successful in the console, but no file is ever uploaded. Is this something you came across, or is there anything you may be able to see I'm doing differently?
const fs = require('fs');
const request = require('request');
var uploadURL = 'http://localhost:80/sandbox/img';
var req = request.post(uploadURL, function (err, resp, body) {
if (err) {
console.log(err);
} else {
console.log(body);
}
});
var form = req.form();
form.append('upload', fs.createReadStream("C:/nodejs/dave/assets/img/brand_logos/logo.jpg"), {
filename: "logo.jpg",
contentType: 'image/jpeg'
});
Below is the response I get, which I'm assuming is expected...
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved here.</p>
<hr>
<address>Apache/2.4.27 (Win64) PHP/7.0.23 Server at localhost Port 80</address>
</body></html>

Download GitLab repository archive using GitLab API and Node.js

I would like to download (not clone) archive from my GitLab repository, but I get this error
incorrect header check (Zlib._handle.onerror)
This is my function:
var fs = require('fs');
var url = require('url');
var https = require('https');
var path = require('path');
var targz = require('tar.gz');
function downloadFile(source, destination, name) {
var options = {
host: url.parse(source).host,
port: 443,
path: url.parse(source).pathname
};
var file = fs.createWriteStream(destination + path.sep + name);
https.get(options, function(res) {
res.on('data', function(data) {
file.write(data);
}).on('end', function() {
file.end();
console.log('File ' + name + ' downloaded to ' + destination);
targz().extract(destination + '/' + name, destination)
.then(function(){
console.log('Job done!');
})
.catch(function(err){
console.log('Something is wrong ', err.stack);
});
});
});
}
The file which is download is type of tar.gz. I try to set some headers but unsuccessful. Source param is like: https://gitlab.com/api/v3/projects/:ID/repository/archive?token=XXYYZZ
Any help please?
The issue is that your file is not correctly downloaded by https module which result in extraction error from tar.gz module.
You can use request module coordinated with tar.gz with createWriteStream to pipe the extraction directly to the destination folder :
var request = require('request');
var targz = require('tar.gz');
function downloadFile(source, destination, cb) {
var read = request.get(source);
var write = targz().createWriteStream(destination);
read.pipe(write);
write.on('finish', function() {
cb(null);
});
write.on('error', function(err) {
cb(err);
});
}
var source = "https://gitlab.com/api/v3/projects/:ID/repository/archive?token=XXYYZZ";
var destination = "/home/user/some/dir";
downloadFile(source, destination, function(err) {
if (err) {
console.log('Something is wrong ', err.stack);
} else {
console.log('Job done!');
}
});
Note that, for the finish event to be dispatched you will need version 1.0.2 of tar.gz (see this issue) :
npm install tar.gz#1.0.2

How to serve (uploaded) images using Meteor

I have this Meteor application in which it is possible to upload images. The uploading parts seem to work. I store the images in .uploads. Now I would like to make these images accessable by the following URL
http://localhost:3000/uploads
After a bit of googling I was able to create the following server side code:
var fs = Meteor.require('fs');
if (Meteor.isServer) {
WebApp.connectHandlers.stack.splice(0, 0, {
route: '/uploads',
handle: function (req, res, next) {
var path = process.env.PWD + '/.' + req.originalUrl.substr(1);
fs.readFile(path, {encoding: 'binary'}, function (err,data) {
if (err) {
throw err;
}
res.writeHead(200, {
'Content-Type': 'image/png'
});
//res.setEncoding("binary"); // this method does not exist
res.write(data);
res.end();
});
}
});
}
This code works, the path constructed is correct and in the browser I receive the 200 code, except it cannot display the image. Something is wrong with the data the browser receives. I checked the image on disk which is fine. So the code above must do something wrong with the data. Any suggestions what that might be?
Here is the code I found after googling (and works for me) a few days ago when I wanted to do what you need to do
files are in .screenshots directory mapped to :
http://localhost:3000/screenshots
code :
//directly serve screenshot files from /.screenshots dir
var fs = Npm.require('fs');
WebApp.connectHandlers.use(function(req, res, next) {
var re = /^\/screenshots\/(.*)$/.exec(req.url);
if (re !== null) { // Only handle URLs that start with /screenshots/*
var filePath = process.env.PWD + '/.screenshots/' + re[1];
var data = fs.readFileSync(filePath, data);
res.writeHead(200, {
'Content-Type': 'image'
});
res.write(data);
res.end();
} else { // Other urls will have default behaviors
next();
}
});

Categories