Определить, когда браузер получает файл загрузки

StackOverflow использует библиотеку Prettify .

451
задан JW. 9 July 2009 в 20:56
поделиться

6 ответов

По моему опыту, существует два способа обработать это:

  1. Набор недолгий cookie на загрузке, и имеет JavaScript, постоянно проверяют на его существование. Только реальная проблема разбирается во времени жизни cookie - слишком короткий, и JS может пропустить ее, слишком долго и она могла бы отменить экраны загрузки для других загрузок. Используя JS для удаления cookie после исследования обычно фиксирует это.
  2. Загрузка файл с помощью fetch/XHR. Мало того, что Вы знаете точно, когда загрузка файла заканчивается при использовании XHR, можно использовать события прогресса для показа индикатора выполнения! Сохраните получающийся блоб с msSaveBlob в IE/краю и ссылке на загрузку ( как этот ) в Firefox/Chrome. Проблема с этим методом состоит в том, что iOS Safari, кажется, не обрабатывает право блобов загрузки - можно преобразовать блоб в URL данных с FileReader и открытый, что в новом окне, но это открывает файл, не сохраняя его.
0
ответ дан 22 November 2019 в 22:55
поделиться

Если вы загрузили файл, который сохранен, а не находится в документе, нет способа определить, когда загрузка завершена, так как это не входит в область действия текущего документ, но это отдельный процесс в браузере.

1
ответ дан 22 November 2019 в 22:55
поделиться

Когда пользователь запускает создание файла, вы можете просто назначить уникальный идентификатор этой «загрузке» и отправить пользователя на страницу который обновляется (или проверяется с помощью AJAX) каждые несколько секунд. Как только файл будет готов, сохраните его под тем же уникальным идентификатором и ...

  • Если файл готов, выполните загрузку.
  • Если файл не готов, покажите ход выполнения.

Затем вы можете пропустить весь беспорядок iframe / wait / browserwindow, но получить действительно элегантное решение.

3
ответ дан 22 November 2019 в 22:55
поделиться

If you don't want to generate and store the file on the server, are you willing to store the status, e.g. file-in-progress, file-complete? Your "waiting" page could poll the server to know when the file generation is complete. You wouldn't know for sure that the browser started the download but you'd have some confidence.

3
ответ дан 22 November 2019 в 22:55
поделиться

У меня была точно такая же проблема. Мое решение заключалось в использовании временных файлов, поскольку я уже создавал кучу временных файлов. Форма отправляется с:

var microBox = {
    show : function(content) {
        $(document.body).append('<div id="microBox_overlay"></div><div id="microBox_window"><div id="microBox_frame"><div id="microBox">' +
        content + '</div></div></div>');
        return $('#microBox_overlay');
    },

    close : function() {
        $('#microBox_overlay').remove();
        $('#microBox_window').remove();
    }
};

$.fn.bgForm = function(content, callback) {
    // Create an iframe as target of form submit
    var id = 'bgForm' + (new Date().getTime());
    var $iframe = $('<iframe id="' + id + '" name="' + id + '" style="display: none;" src="about:blank"></iframe>')
        .appendTo(document.body);
    var $form = this;
    // Submittal to an iframe target prevents page refresh
    $form.attr('target', id);
    // The first load event is called when about:blank is loaded
    $iframe.one('load', function() {
        // Attach listener to load events that occur after successful form submittal
        $iframe.load(function() {
            microBox.close();
            if (typeof(callback) == 'function') {
                var iframe = $iframe[0];
                var doc = iframe.contentWindow.document;
                var data = doc.body.innerHTML;
                callback(data);
            }
        });
    });

    this.submit(function() {
        microBox.show(content);
    });

    return this;
};

$('#myForm').bgForm('Please wait...');

В конце сценария, который генерирует файл, который у меня есть:

header('Refresh: 0;url=fetch.php?token=' . $token);
echo '<html></html>';

Это вызовет событие загрузки в iframe. Затем сообщение ожидания закрывается и начинается загрузка файла. Проверено в IE7 и Firefox.

2
ответ дан 22 November 2019 в 22:55
поделиться

Вопрос в том, чтобы во время генерации файла был индикатор ожидания, а затем возвращался в нормальное состояние после загрузки файла. Мне нравится это делать, используя скрытый iFrame и перехватить событие onload кадра, чтобы моя страница узнала, когда начнется загрузка. НО onload не запускается в IE для загрузки файлов (например, с токеном заголовка вложения). Опрос сервера работает, но мне не нравится дополнительная сложность. Итак, вот что я делаю:

  • Как обычно нацеливаю на скрытый iFrame.
  • Создаю контент. Кэшировать с помощью абсолютный тайм-аут в 2 минуты.
  • Отправить javascript-перенаправление обратно на вызывающий клиент, по сути вызывающий страницу генератора во второй раз. ПРИМЕЧАНИЕ: это приведет к срабатыванию события onload в IE, потому что он работает как обычная страница.
  • Удалите содержимое из кеша и отправить его клиенту.

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

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

public partial class Download : System.Web.UI.Page
{
    protected System.Web.UI.HtmlControls.HtmlControl Body;

    protected void Page_Load( object sender, EventArgs e )
    {
        byte[ ] data;
        string reportKey = Session.SessionID + "_Report";

        // Check is this page request to generate the content
        //    or return the content (data query string defined)
        if ( Request.QueryString[ "data" ] != null )
        {
            // Get the data and remove the cache
            data = Cache[ reportKey ] as byte[ ];
            Cache.Remove( reportKey );

            if ( data == null )                    
                // send the user some information
                Response.Write( "Javascript to tell user there was a problem." );                    
            else
            {
                Response.CacheControl = "no-cache";
                Response.AppendHeader( "Pragma", "no-cache" );
                Response.Buffer = true;

                Response.AppendHeader( "content-disposition", "attachment; filename=Report.pdf" );
                Response.AppendHeader( "content-size", data.Length.ToString( ) );
                Response.BinaryWrite( data );
            }
            Response.End();                
        }
        else
        {
            // Generate the data here. I am loading a file just for an example
            using ( System.IO.FileStream stream = new System.IO.FileStream( @"C:\1.pdf", System.IO.FileMode.Open ) )
                using ( System.IO.BinaryReader reader = new System.IO.BinaryReader( stream ) )
                {
                    data = new byte[ reader.BaseStream.Length ];
                    reader.Read( data, 0, data.Length );
                }

            // Store the content for retrieval              
            Cache.Insert( reportKey, data, null, DateTime.Now.AddMinutes( 5 ), TimeSpan.Zero );

            // This is the key bit that tells the frame to reload this page 
            //   and start downloading the content. NOTE: Url has a query string 
            //   value, so that the content isn't generated again.
            Body.Attributes.Add("onload", "window.location = 'binary.aspx?data=t'");
        }
    }
0
ответ дан 22 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: