Nodejs send data in gzip using zlib - node.js

I tried to send the text in gzip, but I don't know how. In the examples the code uses fs, but I don't want to send a text file, just a string.
const zlib = require('zlib');
const http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html', 'Content-Encoding': 'gzip'});
const text = "Hello World!";
res.end(text);
}).listen(80);

You're half way there. I can heartily agree that the documentation isn't quite up to snuff on how to do this;
const zlib = require('zlib');
const http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html', 'Content-Encoding': 'gzip'});
const text = "Hello World!";
const buf = new Buffer(text, 'utf-8'); // Choose encoding for the string.
zlib.gzip(buf, function (_, result) { // The callback will give you the
res.end(result); // result, so just send it.
});
}).listen(80);
A simplification would be not to use the Buffer;
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html', 'Content-Encoding': 'gzip'});
const text = "Hello World!";
zlib.gzip(text, function (_, result) { // The callback will give you the
res.end(result); // result, so just send it.
});
}).listen(80);
...and it seems to send UTF-8 by default. However, I personally prefer to walk on the safe side when there is no default behavior that makes more sense than others and I can't immediately confirm it with documentation.
Similarly, in case you need to pass a JSON object instead:
const data = {'hello':'swateek!'}
res.writeHead(200, {'Content-Type': 'application/json', 'Content-Encoding': 'gzip'});
const buf = new Buffer(JSON.stringify(data), 'utf-8');
zlib.gzip(buf, function (_, result) {
res.end(result);
});

Related

How can I serve a GZipped file with NodeJS?

I created simple app used angular elements and http node server. To optimize bundle size i just convert the resulting js file to gz format with current command:
"postbuild": "cat dist/cs6-user-widget/{runtime,polyfills,polyfills-es5,scripts,main}.js | gzip > webcomponent/user-widget.js.gz"
The file is created correctly, but i cannot serve this type of content with my node server:
const http = require('http');
const fs = require('fs');
const hostname = 'localhost';
const port = 4202;
http.createServer((request, response) => {
var contentType = 'text/html';
var filePath = './' + request.url;
fs.readFile(filePath, function(error, content) {
if (error) {
fs.readFile('./index.html', function(error, content) {
response.writeHead(200, { 'content-encoding': 'gzip', 'Content-Type': contentType });
return response.end(content, 'utf-8');
});
} else {
response.writeHead(200, { 'content-encoding': 'gzip', 'Content-Type': contentType });
return response.end(content, 'utf-8');
}
});
});
Can You help me to correctly implement node part?
First, please see this answer
If you still want to use node, here is a simple example:
const express = require("express");
const gzipStatic = require("connect-gzip-static");
const app = express();
app.use(gzipStatic(__dirname));
app.listen(4000);

Is there a way to provide file for download using only Node without using express like below?

app.get('/download', function(req, res){
const file = `${__dirname}/upload-folder/dramaticpenguin.MOV`;
res.download(file); // Set disposition and send it.
});
Here's a super simple example that should give you a start on how to implement this without express:
const http = require('http');
const fs = require('fs');
const path = require('path');
const httpServer = http.createServer(requestResponseHandler);
function requestResponseHandler(req, res) {
if (req.url === '/download') {
const file = `${__dirname}/sample-video.mov`;
res.writeHead(200, {
'Content-Type': 'video/quicktime',
'Content-Disposition': 'attachment; filename="sample.mov',
});
fs.createReadStream(file).pipe(res);
}
}
httpServer.listen(3000, () => {
console.log('server is listening on port 3000');
});
Basically all it does is to set the correct content-type and content-disposition headers and the create a read-stream from the mov-file and pipe this stream into the response-object.

Node.js send HTML as response to client

Is it possible in Node.js to return HTML (e.g. <div>Test</div>) as response to client?
I saw that option in Express on sendFile() method().
Is there something similar in Node?
I found this solution:
var myHtmlData;
fs.readFile('./index.html', (err, data) => {
if(err){
throw err;
} else {
myHtmlData = data
}
})
// and after use it
response.write(myHtmlData)
But I was wondering is it possible to do it with some method similar to sendFile() to write html directly like this <div>Test</div> without reading it from another file.
Sure. It's pretty simple. The following code returns the response as HTML to the client.
var http = require('http');
http.createServer(function(req, res){
if(req.url === "/"){
res.writeHead(200, { 'Content-Type':'text/html'});
res.end("<div><p>Test<p></div>");
}
}).listen(3000);
And in case you want to serve an HTML or JSON file as a response, you can execute the following code.
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res){
if(req.url === '/I_want_json'){
res.writeHead(200, { 'Content-Type':'application/json'});
var obj = {
firstName: "Jane",
lastName: "Doe",
};
res.end(JSON.stringify(obj));
}
else if (req.url === '/I_want_html'){
res.writeHead(200, { 'Content-Type':'text/html'});
html = fs.readFileSync('./index.html');
res.end(html);
}
else{
res.writeHead(404);
res.end();
}
}).listen(3000, '127.0.0.1');
Do not forget to set the Content-Type as mentioned since it is a mandatory part for client to distinguish the type of response.
First, you need to mention the content type as HTML. Then read the HTML file using fs module and send its data as a response. Don't forget to end the response using end() method.
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
res.setHeader("Content-Type", "text/html");
fs.readFile('./views/index.html', (err, data) => {
if(err) {
console.log(err);
res.end();
} else {
res.write(data);
res.end();
}
})
});

NodeJS - Server Side File Upload Handler

i'm trying to develop a simple file upload handler.
the only thing that i want is , this app receives a file from client and saves on hdd.
(i don't want to upload a file with nodejs , i just want to receive a file upload post and save it on my hdd)
how can i do this ?
i'm tried this way but , it does not works as expected.
var http = require('http'),
path = require('path'),
os = require('os'),
fs = require('fs');
var Busboy = require('busboy');
http.createServer(function(req, res) {
if (req.method === 'POST') {
try{
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
var fstream = fs.createWriteStream('asdasd');
file.pipe(fstream);
fstream.on('close', function () {
res.writeHead(200, { 'Connection': 'close' });
res.send('upload succeeded!');
});
/*var saveTo = path.join(os.tmpDir(), path.basename(fieldname));
file.pipe(fs.createWriteStream('./output.asdasd'));
fstream.*/
});
busboy.on('finish', function() {
res.writeHead(200, { 'Connection': 'close' });
res.end("That's all folks!");
});
return req.pipe(busboy);
}
catch(err){
console.log('error : ' + err);
res.writeHead(404);
res.end();
}
}
res.writeHead(404);
res.end();
}).listen(4842, function() {
console.log('Listening for requests');
});
I've never used busboy before but the example given over in their GitHub documentation works fine.
let http = require('http'),
path = require('path'),
os = require('os'),
fs = require('fs');
let Busboy = require('busboy');
http.createServer(function (req, res) {
if (req.method === 'POST') {
let busboy = new Busboy({ headers: req.headers });
// handle all incoming `file` events, which are thrown when a FILE field is encountered
// in multipart request
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
// figure out where you want to save the file on disk
// this can be any path really
let saveTo = path.join(os.tmpdir(), path.basename(filename));
// output where the file is being saved to make sure it's being uploaded
console.log(`Saving file at ${saveTo}`);
// write the actual file to disk
file.pipe(fs.createWriteStream(saveTo));
});
busboy.on('finish', function () {
res.writeHead(200, { 'Connection': 'close' });
res.end("That's all folks!");
});
return req.pipe(busboy);
}
res.writeHead(404);
res.end();
}).listen(8000, function () {
console.log('Listening for requests');
});
I've added some comments in the relevant section to make it more clear how it works. If you need more details, just comment below and I'll add them.
Simply use the FS api from node to write data received on file ? :)
https://nodejs.org/api/fs.html#fs_class_fs_writestream
Solved ,
i'm tried it with postman , i changed my mind and tried it with RESTClient , it works successfully now :)

curl, node: posting JSON data to node server

I'm trying to test a small node server I've written with CURL and for some reason this fails. My script looks like this:
http.createServer(function (req, res)
{
"use strict";
res.writeHead(200, { 'Content-Type': 'text/plain' });
var queryObject = url.parse(req.url, true).query;
if (queryObject) {
if (queryObject.launch === "yes") {
launch();
else {
// what came through?
console.log(req.body);
}
}
}).listen(getPort(), '0.0.0.0');
When I point my browser to:
http://localhost:3000/foo.js?launch=yes
that works fine. My hope is to send some data via JSON so I added a section to see if I could read the body part of the request (the 'else' block). However, when I do this in Curl, I get 'undefined':
curl.exe -i -X POST -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://localhost:3000/foo.js?moo=yes
I'm not sure why this fails.
The problem is that you are treating both requests as if they where GET requests.
In this example I use a different logic for each method. Consider that the req object acts as a ReadStream.
var http = require('http'),
url = require('url');
http.createServer(function (req, res) {
"use strict";
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
req.on('end', function () {
console.log("Body: " + body);
});
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('post received');
} else {
var queryObject = url.parse(req.url, true).query;
console.log("GET");
res.writeHead(200, {'Content-Type': 'text/plain'});
if (queryObject.launch === "yes") {
res.end("LAUNCHED");
} else {
res.end("NOT LAUNCHED");
}
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
}).listen(3000, '0.0.0.0');

Resources