Приостановка / возобновление потока NodeJS не работает с XMLHttpRequest, но работает с curl? - PullRequest
2 голосов
/ 22 марта 2012

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

У меня есть такой код (используя restify):

server.put("/whatever", function (serverRequest, serverResponse, next) {
    serverRequest.pause();

    serverRequest.on("data", function (chunk) {
        console.log("from outside", chunk);
    });

    doSomeAsyncStuff(function (err) {
        serverRequest.on("data", function (chunk) {
            console.log("from inside", chunk);
        });
        serverRequest.on("end", function () {
            next();
        });

        serverRequest.resume();
    });
});

Когда я нажимаю на этот сервер, используя CURL, это прекрасно работает. Но когда я проверяю это с помощью XMLHttpRequest, я получаю на одну "from inside" строку журнала меньше, чем я "from outside" строки журнала. Кажется, что одно из событий данных теряется, несмотря на все мои попытки сделать паузу как можно скорее.


Вот команда CURL, которую я использую:

curl -X PUT -T file.pdf http://localhost:7070/whatever -v

А вот код XMLHttpRequest (работает в последних версиях Chrome):

var arrayBuffer = fromElsewhere();
var xhr = new XMLHttpRequest();

xhr.open("PUT", "http://localhost:7070/whatever");
xhr.setRequestHeader("Content-Length", arrayBuffer.byteLength);
xhr.setRequestHeader("Content-Type", "application/pdf");
xhr.send(arrayBuffer);

Одно заметное отличие состоит в том, что CURL, похоже, отправляет Expect: 100-continue перед загрузкой, тогда как XMLHttpRequest - нет. Я попытался добавить этот заголовок вручную, но, конечно, он на самом деле мало что сделал (т.е. Chrome не ждал ответа, он просто отправил все данные PDF вместе с исходным запросом). Несмотря на это, я не знаю, почему это повлияет на ситуацию.

1 Ответ

4 голосов
/ 22 марта 2012

Довольно предсказуемо, это не имело никакого отношения к скручиванию против XMLHttpRequest, но вместо этого к факту, что serverRequest.pause является только рекомендательным;это на самом деле не делает паузу сразу .То есть, это в значительной степени бесполезно.

Так что, вероятно, в случае CURL время было достаточно хорошим, чтобы pause действительно работало, как ожидалось, тогда как в случае XMLHttpRequest время было выключено, и один из"from outside" data событиям удалось проскользнуть через «консультативную» паузу.

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

Я добавил запрос на получение документации в надежде, что никто другой не попытается использовать pause при условии, что он действительно работает.

...