5

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.
srlm
  • 3,186
  • 2
  • 27
  • 40
  • 1
    You're right, that's not easily possible with PhantomJS. See [my answer here](http://stackoverflow.com/a/24561614/1816580). It is for CasperJS, but applies also for PhantomJS. – Artjom B. Apr 13 '15 at 09:43
  • It seems like you're overthinking this and you could just write integration/unit tests using your server side programming language. Since it's your API, you should have access to the source code and therefore you can mock the requests/responses as needed. – Cameron Tinker Apr 20 '15 at 17:46

1 Answers1

1

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.

clearfix
  • 467
  • 1
  • 5
  • 10