NodeJS PhantomJS screenshot via Express
In my first blog post about NodeJS, I thought it would neat to utilize PhantomJS to fetch a URL, take a screenshot, and serve it back to the user as a static asset.
Install NodeJS & PhantomJS via brew, if you haven’t already:
brew install node
brew install phantomjs
Create a new directory, and define a new file: package.json, contents:
{
"name": "phantomjs_screenshot",
"description": "phantomjs screeshot",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "3.x",
"phantom": "*",
"jade": "*"
}
}
Install dependencies:
npm install
I used Express to handle the routes and serve static assets, and Jade as the HTML middleware.
I create a views subdirectory for Jade with a new layout, file: views/layout.jade
doctype html
html(lang="en")
head
title #{title}
body
header
h1 #{title}
.container
block content
And another view file for the index page, which creates a form with an input element for URL. file: views/index.jade.
extend layout
block content
form(name="process_url", action="/process_url", method="post")
input(type="text", name="url")
input(type="submit", value="Submit")
I then created the main app file “app.js” to run the server.
var express = require('express');
var app = express();
// define the public directory for static assets
var public_dir = __dirname + '/public';
// setup express
app.use(express.compress());
app.use(express.static(public_dir));
app.use(express.json());
app.use(express.urlencoded());
// setup jade
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
// route: get: /
app.get('/', function (req, res) {
res.render('index',
{ title : 'NodeJS PhantomJS Screenshot' }
)
});
// route: post: /process_url
app.post('/process_url', function (req, res) {
// get url to process
var url_to_process = req.body.url;
if (url_to_process === undefined || url_to_process == '') {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end("404 Not Found");
}
// phantomjs screenshot
var phantom = require('phantom');
phantom.create(function(ph){
ph.createPage(function(page){
page.open(url_to_process, function(status){
if (status == "success") {
// put images in public directory
var image_file_name = url_to_process.replace(/\W/g, '_') + ".png"
var image_path = public_dir + "/" + image_file_name
page.render(image_path, function(){
// redirect to static image
res.redirect('/'+image_file_name);
});
}
else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end("404 Not Found");
}
page.close();
ph.exit();
});
});
});
});
// start server
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
Start the app. Browse to http://localhost:3000 and submit a URL.
node app.js