HTTP Потоковое с Apache, Perl и JQuery? - PullRequest
2 голосов
/ 09 сентября 2010

Я пытаюсь подготовить подтверждение концепции для страницы, которая будет принимать файл, который выбирает пользователь, обрабатывать и возвращать его, все время сообщая о состоянии процесса. Я думал, что лучшим решением для этого может быть потоковая передача по HTTP, однако я могу заставить его работать только в Firefox (не в Chrome или IE8.)

load.js

$(function() {
        var xhr = $.ajax({
                url: '/nph-handleRequest.cgi'
                ,type: 'get'
        });

        collectPartial(xhr,'');
});

var collectPartial = function (xhr,lastContent) {
        alert(xhr.readyState);
        if (xhr.readyState == 3 && lastContent != xhr.responseText) {
                lastContent = xhr.responseText;
                alert(xhr.responseText);
        }
        if (xhr.readyState < 4) {
                setTimeout(function() {collectPartial(xhr,lastContent)}, 1000);
        }
}

НПХ-handleRequest.cgi

#!/usr/bin/perl
$|=1;
print "$ENV{SERVER_PROTOCOL} 206 Partial Content\n";
print "Server: $ENV{SERVER_SOFTWARE}\n";
print "Content-type: text/plain\n\n";
for ($count = 1; $count < 5; $count++) {
        print time();
        print "\n";
        sleep(2);
}

В Firefox предупреждение (xhr.readyState) продолжает отображать 3, как я и ожидал. В Chrome, правда? 1. В IE это 2. Ни один не позволяет мне получить доступ к responseText либо.

Любые предложения относительно того, что я делаю неправильно, будут с благодарностью.

Редактировать 1

На самом деле это MiniServ, а не Apache. Сервер, похоже, не является проблемой, поскольку он работает в одном браузере, а не в другом.

Редактировать 2

После обнаружения CGI :: Push я попытался использовать это, несмотря на предупреждения, что это не работает в IE. Как ни странно, он работал в IE8 (не идеально), но все еще не в Chrome.

#!/usr/bin/perl
$|=1;
use CGI::Push qw(:standard);

do_push(-next_page=>\&display_time,-delay=>2);

sub display_time {
        my($q,$counter) = @_;
        return undef if $counter > 5;
        return time()," "x256, "\n";
}

Ответы [ 2 ]

4 голосов
/ 09 января 2011

Я согласен с Xaxxon. Было время, когда некоторые веб-сайты пытались сделать «поддельный AJAX», заставляя сервер время от времени выводить символы прогресса, чтобы браузер ожидал завершения процесса, но у каждого браузера были свои правила ожидания и буферизации.

Лучший способ сделать это - это, чтобы запросы AJAX из javascript на странице опрашивали сервер каждые n секунд, спрашивая его, выполнена ли работа, и когда это происходит, отображая результаты. Это должно быть намного надежнее, и вы даже можете заставить код отказаться от сообщения об ошибке, если сервер перестает отвечать или задание занимает слишком много времени.

2 голосов
/ 09 января 2011

Я бы предложил, чтобы вы выбрали другой подход.Когда пользователь загружает файл, вы создаете какое-то задание на стороне сервера и перенаправляете пользователя на страницу со статусом задания (или делаете это через ajax).Затем, когда работа будет завершена, представьте им обработанный файл.

Попытка сделать это за один шаг HTTP вызывает проблемы, подобные той, которую вы видите в разных браузерах (и, возможно, на разных веб-серверах, если выкогда-нибудь хотел поменять тот, который вы используете) на другое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...