Почему функция Node.js не возвращает результат JSDom serializeDocument?

У меня есть PHP-скрипт, который действует как клиент DNode. Затем у меня есть сервер Node.js Dnode, который оценивает код, который получает от клиента PHP, и возвращает DOM как HTML. Тем не менее, Node.js действует странно для меня (будучи новичком Node.js). Он ничего не возвращает, даже если возвращаемая строка не пуста. Мой код ниже:

Клиентский код PHP с использованием библиотеки DNode-PHP:

<?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:

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 () четко выводит <!DOCTYPE html><html><head></head><body><a></a></body></html> каков ожидаемый результат. Но это никогда не добирается до клиента PHP. Но что странно, если я меняю линию cb(html); в cb('test');PHP выводит "тест". Так что проблема должна быть где-то на стороне Node.js. Но я понятия не имею, где искать.

Заранее спасибо за любые подсказки.

2 ответа

Решение

Как вы смотрите ответ? Через веб-браузер? Если это так, то вы зависите от того, что вы оцениваете в eval(n) изменить DOM документа... Если ничего не изменится, вы ничего не увидите, потому что у вас будет пустой DOM, кроме html/head/body теги. Это будет стоить вашего времени, чтобы подтвердить, что вы получаете пустой ответ, а не просто DOM.

Как говорится, eval Функция имеет какой-либо контекст, который вы хотите выполнить на document/window Вы заявляете выше. Как это, это просто выполняется в контексте node сам по себе, а не на странице, которую вы пытаетесь создать. Чтобы это исправить, попробуйте использовать:

window.eval(n)

Если вы посмотрите на пример Creating a browser-like window object на странице Github для jsdom, это даст вам лучшее представление о том, как именно использовать этот пакет.

https://github.com/tmpvar/jsdom

То, что у вас есть выше, должно выглядеть примерно так:

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

window.eval(n);

var html = jsdom.serializeDocument(document);

cb(html);

Теперь вы будете выполнять Javascript на DOM, который вы ранее создавали:-)

Ваша проблема не в узле. Когда я использую код сервера, который вы показываете в своем вопросе, и пытаюсь использовать этот код клиента, я получаю ожидаемый результат:

var dnode = require("dnode");

var d = dnode();
d.on('remote', function (remote) {
    var js = 'var a = document.createElement("A");' +
             'document.getElementsByTagName("body")[0].appendChild(a);';
    remote.zing(js, function (s) {
        console.log(s);
    });
});
d.connect('localhost', '7070');

Я не делаю PHP, поэтому я не знаю, в чем проблема может быть на этой стороне.

Другие вопросы по тегам