javascriptphpnode.jsdnode

Why Node.js function doesn't return JSDom serializeDocument result?


I have PHP script which acts as a DNode client. Then I have Node.js Dnode server which evaluates code which receives from PHP client and it returns DOM as HTML. However, Node.js acts strangely to me (beeing a Node.js newbie). It doesn't return anything, even though the returning string is not empty. My code is below:

PHP client code using DNode-PHP library:

<?php
  require(__DIR__.'/../../vendor/autoload.php');
  $loop = new React\EventLoop\StreamSelectLoop();
  $dnode = new DNode\DNode($loop);
  $dnode->connect(7070, function($remote, $connection) {
    $js = 'var a = document.createElement("A");';
    $js.= 'document.getElementsByTagName("body")[0].appendChild(a);'
    $remote->zing($js, function($n) use ($connection) {
      print_r($n);
      $connection->end();
  });
});
$loop->run();
?>

Node.js server code:

var dnode = require('dnode');
var jsdom = require("jsdom");
var server = dnode({
  zing: function (n, cb) { 
    var document = jsdom.jsdom('<!DOCTYPE html>');
    var window = jsdom.parentWindow;
    eval(n);
    var html = jsdom.serializeDocument(document);
    // console.log(html);
    cb(html);
  }
});
server.listen(7070);

Console.log() clearly outputs <!DOCTYPE html><html><head></head><body><a></a></body></html> what is expected result. But it never gets to PHP client. But what is strange, if I change line cb(html); to cb('test');, PHP outputs "test". So the problem must be somewhere on the Node.js side. But I have no idea where to look for.

Thanks in advance for any hints.


Solution

  • How are you viewing the response? Through a web browser? If so, then you're depending on whatever you're evaluating in eval(n) to change the DOM of the document... If nothing changes, then you won't end up seeing anything because you'll have an empty DOM other than the html/head/body tags. It would be worth your time confirming that you're getting an empty response back and it's not just an empty DOM.

    That being said, The eval function has any context of you wanting to execute it on the document/window you declare above. As it is, it is just executing in the context of node itself, not on the page you are attempting to create. To fix this, try using:

    window.eval(n)

    If you take a look at the example Creating a browser-like window object on the Github page for jsdom, this will give you a better idea of how exactly to use this package.

    https://github.com/tmpvar/jsdom

    What you have above should look something like this:

    var document = jsdom.jsdom("<!DOCUMENT html>");
    var window = document.parentWindow;
    
    window.eval(n);
    
    var html = jsdom.serializeDocument(document);
    
    cb(html);
    

    Now you'll be executing the Javascript on the DOM you were previously creating :-)