Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept Requests With Custom Responses in PhantomJS?

Tags:

phantomjs

Is there a way to intercept a resource request and give it a response directly from the handler? Something like this:

page.onRequest(function(request){
   request.reply({data: 123});
});

My use case is for using PhantomJS to render a page that makes calls to my API. In order to avoid authentication issues, I'd like to intercept all http requests to the API and return the responses manually, without making the actual http request.

onResourceRequest almost does this, but doesn't have any modification capabilities.

Possibilities that I see:

  1. I could store the page as a Handlebars template, and render the data into the page and pass it off as the raw html to PhantomJS (instead of a URL). While this would work, it would make changes difficult since I'd have to write the data layer for each webpage, and the webpages couldn't stand alone.
  2. I could redirect to localhost, and have a server there that listens and responds to the requests. This assumes that it would be ok to have an open, un-authenticated version of the API on localhost.
  3. Add the data via page.evaluate to the page's global window object. This has the same problems as #1: I'd need to know a-priori what data the page needs, and write server side code unique to each page.
like image 822
srlm Avatar asked Nov 09 '22 16:11

srlm


1 Answers

I recently needed to do this when generating pdfs with phantom js. It's slightly hacky, but seems to work.

var page = require('webpage').create(),
  server = require('webserver').create(),
  totallyRandomPortnumber = 29522,
  ...
//in my actual code, totallyRandomPortnumber is created by a java application,
//because phantomjs will report the port in use as '0' when listening to a random port
//thereby preventing its reuse in page.onResourceRequested...

server.listen(totallyRandomPortnumber, function(request, response) {
  response.statusCode = 200;
  response.setHeader('Content-Type', 'application/json;charset=UTF-8');
  response.write(JSON.stringify({data: 'somevalue'}));
  response.close();
});

page.onResourceRequested = function(requestData, networkRequest) {
    if(requestData.url.indexOf('interceptme') != -1) {
        networkRequest.changeUrl('http://localhost:' + totallyRandomPortnumber);
    }
};

In my actual application I'm sending some data to phantomjs to overwrite request/responses, so I'm doing more checking on urls both in server.listen and page.onResourceRequested. This feels like a poor-mans-interceptor, but it should get you (or whoever this may concern) going.

like image 185
clearfix Avatar answered Jan 03 '23 02:01

clearfix