Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an Express server as a convenient Node wrapper. #15

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
node_modules
*.sh
newrelic*
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,15 @@ if ($args ~ _escaped_fragment_) {
# Proxy to PhantomJS instance here
}
```

Running using Node and Express
==============================

Running PhantomJS jobs as a daemon on the server can be very tricky. One solution is to wrap PhantomJS in a regular Node server. The Node server can be run as a daemon using [forever](https://github.com/nodejitsu/forever)

To use Express, first ```npm install``` to retrieve all Node dependencies. Next run something like ```node express-server.js 8888 http://myserver.com/``` or ```forever start express-server.js 8888 http://myserver.com/```

The Express server behaves very similarly to angular-seo-server.js; however, it does not at this time take any options as arguments. All PhantomJS options are hardcoded.

[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/3a55c16a191c4c8222beddcf429c2608 "githalytics.com")](http://githalytics.com/steeve/angular-seo)

2 changes: 2 additions & 0 deletions angular-seo-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ var renderHtml = function(url, cb) {
page.onInitialized = function() {
page.evaluate(function() {
setTimeout(function() {
if (typeof window.callPhantom === 'function') {
window.callPhantom();
}
}, 10000);
});
};
Expand Down
85 changes: 85 additions & 0 deletions express-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require('newrelic');
var app = require('express')(),
port = process.argv[2],
prefix = process.argv[3],
phantom = require('phantom'),
noCache = '--disk-cache=no',
noSSL = '--ignore-ssl-errors=true',
noImages = '--load-images=false',
allowRemote = '--local-to-remote-url-access=yes',
REGEX = /_escaped_fragment_=([^&]+)/,
portCounter = 12300;

var parse_qs = function(s) {
var fragment = s.match(REGEX);
if (fragment.length > 1) {
return fragment[1];
}

};

var renderHtml = function(url, cb) {
portCounter += 1;

console.log('PhantomJS query: ' + url + ' using port ' + portCounter + '.');

phantom.create(noCache, noSSL, noImages, allowRemote, {port: portCounter}, function (ph) {
ph.createPage(function (page) {

page.set('onLoadFinished', function() {
page.get('content', function (content) {
cb(content);
page.release();
page.close();
page = null;
if (portCounter > 13300) {
portCounter = 12300;
}


});

});

// page.onConsoleMessage = function(msg, lineNum, sourceId) {
// console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
// };
// page.onResourceReceived = function(response) {
// console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response));
// };

page.set('onInitialized', function() {
page.evaluate(function() {
setTimeout(function() {
window.callPhantom();
}, 10000);
});
});

page.open(url);
})
});



};

app.get('/', function (req, res) {
var route = parse_qs(req.url),
callback = function (html) {
res.send(html);
},
url = prefix
+ req.url.slice(1, req.url.indexOf('?'))
+ '?phantomjs=true'
+ '#!' + decodeURIComponent(route);

renderHtml(url, callback);

});

app.listen(port);


console.log('Listening on ' + port + '...');
console.log('Press Ctrl+C to stop.');
30 changes: 30 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "angular-seo",
"version": "0.0.0",
"description": "PhantomJS-based SEO tools for Angular.",
"main": "express-server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git://github.com/deltaepsilon/angular-seo.git"
},
"keywords": [
"angular",
"seo",
"phantomjs",
"phantomjs-node",
"node"
],
"author": "Christopher Esplin <[email protected]> (http://christopheresplin.com/)",
"license": "BSD-2-Clause",
"bugs": {
"url": "https://github.com/deltaepsilon/angular-seo/issues"
},
"dependencies": {
"express": "~3.4.4",
"phantom": "git://github.com/sgentle/phantomjs-node.git#e029778ec4",
"newrelic": "~1.2.0"
}
}