Can ExpressJs compression compress on http request other than static file? - javascript

I'm using express 4.x and have turned on compression middleware in my app.js like this:
var compression = require('compression');
var app = express();
app.use(compression());
app.use('/', require('./static'));
app.use('/api/xxx', require('./api/xxx'));
When I check in Safari web inspector, some files, like my app.js is indeed compressed, you can see a difference (though small) in file size:
but others like api requests are not:
There seems to be no difference in size, given that my server simply sends json on request, why the data transferred are not heavily compressed?

it is because you need to set the compression level.
Read the documentation here: https://github.com/expressjs/compression
Mine is set for max compression like so:
// Compress content
app.use(compression({
level: 9,
memLevel: 9
}));

Related

How to store an image to my computer from SimpleHTTPServer?

I am using SimpleHTTPServer to serve a directory and run and html code locally. There, I use getusermedia api to take some pictures. If I use js localstorage to store the pictures, where are they stored exactly? How can I copy them to a known directory?
The browser usually manages the localStorage and sessionStorage variables in an encrypted, completely private area so that your browsing experience is as safe as possible (imagine if you could read and write someones files whenever they visit your web page!!).
You cannot copy the images to or from the clients computer without their knowing. You can however, cause automatic downloads server-side.
As for saving a previously downloaded image, see:
How to save an image to localStorage and display it on the next page?
However, do note, that the maximum storage space is usually capped, with sizes wildly varying between browsers and their relative environments.
My own test suggest Chromium will only support 10x 5mb files by default.
Edit:
As for copying to a known directory, you must send the file back you your http server and collect them from there. You may use ajax if you would choose, by converted the data to base64, enabling you to send the data in a json string ('failure to encode the data will results in errors'), and collect on server side with new Buffer(str,"base64").toString("binary")
var http = require('http'),
cluster = require('cluster'),
path = require('path')
url = require('url')
util = require('util')
function posthandler(request,response){
if(request.url=="/image_streamer"){
var datum = [];
request.on('data',function(d){datum.push(d);});
request.on('end',function(){
datum = JSON.parse(datum.join("").toString('utf8'));
datum.image = new Buffer(datum.image,"base64");
// datum.image NOW POINTS TO A BINARY BUFFER :) HAPPY DAYS.
});
}
}
var server = http.createServer(function(request,response){
switch(request.method){
case: "GET":{} break;
case: "POST":{posthandler(request,response);} break;
};
}).listen(8080);

downloading binary file over REST API

I've got a big system where I need to generate a PDF file. I'd like to access it via REST API and, of course, store the file locally.
The file content depends on many parameters what the content of this file should be, i.e. time: from-to, filters, sorting and many, many more parameters; they form a JSON object which perfectly fits into POST parameters. The parameters cannot go through GET, since they're too big.
There is the FileSaver library that works perfectly fine on modern browsers. I created an online demo. But when I downloaded old browsers - firefox11, firefox12, firefox15, it didn't work at all, even though I included the Blob.js polyfill - it opened a new tab with URL like: blob:457-343457-34574567-4576456 that was unable to be saved. I need to support many browsers, not only the new ones.
The question is - I've got JSON parameters object inside my SPA app - how should I design this PDF binary file download?
I was thinking of 3 approaches:
force browser to create a file on localhost - using FileSaver. WOrks fine for modern browsers, doesn't work for old ones
create downloadable link. I shoot a POST to the REST API, incuding all parameters, the REST API returns something like: {"download": "mysite.com/download/ms2h5d34h53m"}, the response is used to display a link to the user; the user might click the link (with no AJAX) and the server-side API should just return a file like in the old times.
not mine, but somewhere I read I could create an invisible form that shoots a POST to the server, which triggers file download (perhaps this would reduce the step with returning the {"download": "mysite.com/download/ms2h5d34h53m"} JSON)
I need a guidance on how to do that right.
I tried to create a test express.js server below. When I access http://localhost:8081/download directly, I see a PDF file downloaded locally. But when I try to access it via ajax/js:
then the content is fetched as binary stream:
var fs = require('fs');
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
});
app.get('/download', function(req, res){
var file = fs.readFileSync(__dirname + '/example.pdf', 'binary');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Length', file.length);
res.setHeader('Content-Disposition', 'attachment; filename=new-name.pdf');
res.setHeader('filename', 'sample.pdf');
res.write(file, 'binary');
res.end();
});
var server = app.listen(8081, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});

Match all routes with or without .html extension, except for static assets

I'm trying to set up a generic handler for every request that is not something like an image or favicon or anything like that. For example I want this handler to handle /index, /index.html, /user/123, etc., but not /favicon.ico, /sunflower.png, /images/starfish.png, etc.
This is currently what I have
app.get('/:name', (req, res) => {
res.render(req.params.name)
})
But this is of course matching /favicon.ico, and every other url that I don't want it to match. It also doesn't match .html extensions. Is there a clean solution out there for this situation?
The best solution in a production environment to serve static assets, like the images you have listed, is to place a front facing proxy (eg: nginx) in front of Express and configure it accordingly.
That way, request for static assets are offloaded to the proxy, and never reach Express. Express is best for serving dynamic content asynchronously, do not use it for serving files.

How do I send images and javascript files to the browser using Node js

I have created a Node.js server that worked well when the Javascript was part of the HTML page. I moved the JS to another file and added some images. Now it won't load the images or the JS into the browser. However, the web page renders perfectly when I open the web page directly. This is what my server looks like:
app.get('/',function(req,res){
res.end('Hello World!Go to /map to see the google map');
});
app.get('/map',function(req,res){
var conn;
//images must be sent to the client from the server...
res.sendfile(__dirname+'/client/google_maps.html');
//receiving requests from jQuery
});
I am not using the Express project structure or the Express middleware or Express configuration to do this.
If that's all your code, I think the problem you met is reasonable. You didn't tell your server how to respond your images and scripts when browser requested. For example in your google_map.html file you have <script src="myjs.js"></script>, then your browser will ask your node application to give the content of myjs.js but your server don't know how to deal with it.
You could try to add code like below to see if it helps.
app.get('/myjs.js', function (req, res) {
res.sendfile(__dirname + '/myjs.js');
});
As dimadima said, Express provides a module to handle static files that you can use like
app.use(express.static(__dirname + '/public'));

Static image file is invisible in node.js/express

The following code is an exemple of code to serve static files in express on node.js. If I ask the server a .css file there is no problem, but if I ask an image such as a jpg or png, it loads a white page (no /GET error or anything, a simple white page). In my developer tool in my browser I see the following warning: 1Resource interpreted as Document but transferred with MIME type image/jpeg. How can I fix this?
I am using cloud9ide and express 2.4.6
var express = require("express"),
app = express.createServer();
app.use(express.static(__dirname + '/static'));
app.get('/', function(req, res){
res.send('Hello World');
});
app.listen(process.env.C9_PORT);
It looks like the file in question is not in JPEG format. Can you save that URL as a file using wget, curl or similar tools and open that file in a text editor?
A valid JPEG file should look like binary garbage and should have "JFIF" signature string close to the beginning (byte offset 6 I think).
it is possible that the file contains an error message instead of valid JPEG data.
It seems to be a bug from cloud9 ide. I tried my code locally and it worked. There is a ticket open on cloud9ide at: http://cloud9ide.lighthouseapp.com/projects/67519/tickets/390-get-png-image-not-working-in-preview-mode#ticket-390-4

Categories