JS / jQuery прослушать отмену смены страницы из-за загруженного файла [дубликат]

Вам нужен список идентификаторов? Если да, попробуйте:

- debug: msg="{{ lookup('file','test.json') | from_json | json_query(query) }}"
  vars:
    query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"

Сначала создайте простые объекты с необходимыми полями, а затем подключите их к фильтру.

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

15 ответов

Одно возможное решение использует JavaScript на клиенте.

Клиентский алгоритм:

  1. Создает случайный уникальный токен.
  2. Отправьте запрос на загрузку и включите токен в поле GET / POST.
  3. Покажите индикатор ожидания.
  4. Запустите таймер и каждую секунду или около того, найдите файл cookie с именем «fileDownloadToken» (или все, что вы решите).
  5. Если файл cookie существует и его значение соответствует токену, скройте индикатор ожидания.

Алгоритм сервера:

  1. Ищите поле GET / POST в запросе.
  2. Если у него есть непустое значение, отбросьте файл cookie (например, "fileDownloadToken ") и установите его значение в значение маркера.

Исходный код клиента (JavaScript):

function getCookie( name ) {
  var parts = document.cookie.split(name + "=");
  if (parts.length == 2) return parts.pop().split(";").shift();
}

function expireCookie( cName ) {
    document.cookie = 
        encodeURIComponent(cName) + "=deleted; expires=" + new Date( 0 ).toUTCString();
}

function setCursor( docStyle, buttonStyle ) {
    document.getElementById( "doc" ).style.cursor = docStyle;
    document.getElementById( "button-id" ).style.cursor = buttonStyle;
}

function setFormToken() {
    var downloadToken = new Date().getTime();
    document.getElementById( "downloadToken" ).value = downloadToken;
    return downloadToken;
}

var downloadTimer;
var attempts = 30;

// Prevents double-submits by waiting for a cookie from the server.
function blockResubmit() {
    var downloadToken = setFormToken();
    setCursor( "wait", "wait" );

    downloadTimer = window.setInterval( function() {
        var token = getCookie( "downloadToken" );

        if( (token == downloadToken) || (attempts == 0) ) {
            unblockSubmit();
        }

        attempts--;
    }, 1000 );
}

function unblockSubmit() {
  setCursor( "auto", "pointer" );
  window.clearInterval( downloadTimer );
  expireCookie( "downloadToken" );
  attempts = 30;
}

Пример кода сервера (PHP):

$TOKEN = "downloadToken";

// Sets a cookie so that when the download begins the browser can
// unblock the submit button (thus helping to prevent multiple clicks).
// The false parameter allows the cookie to be exposed to JavaScript.
$this->setCookieToken( $TOKEN, $_GET[ $TOKEN ], false );

$result = $this->sendFile();

Где:

public function setCookieToken(
    $cookieName, $cookieValue, $httpOnly = true, $secure = false ) {

    // See: http://stackoverflow.com/a/1459794/59087
    // See: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
    // See: http://stackoverflow.com/a/3290474/59087
    setcookie(
        $cookieName,
        $cookieValue,
        2147483647,            // expires January 1, 2038
        "/",                   // your path
        $_SERVER["HTTP_HOST"], // your domain
        $secure,               // Use true over HTTPS
        $httpOnly              // Set true for $AUTH_COOKIE_NAME
    );
}
389
ответ дан David Passmore 28 August 2018 в 16:45
поделиться
  • 1
    Удивительная идея, я использовал ее как базовую структуру для этого ответа о загрузке нескольких файлов с помощью jQuery / C # – Greg 29 January 2012 в 02:53
  • 2
    Головы для других: если document.cookies не включает downloadToken, проверьте путь к файлу cookie. В моем случае мне пришлось установить путь к & quot; / & quot; на стороне сервера (например, cookie.setPath («/») в Java), хотя по умолчанию путь был пустым. Некоторое время я думал, что проблема связана с обработкой cookie домена «localhost» ( stackoverflow.com/questions/1134290/… ), но это не было проблемой в конце. Может быть, для других, хотя так стоит прочитать. – jlpp 3 April 2014 в 20:10
  • 3
    @bulltorious, прежде чем углубляться с вашим решением, интересно, будет ли он работать с запросом на загрузку файла с несколькими доменами. Считаете ли вы, что это будет, или ограничения cookie будут скомпрометировать его? – kiks73 9 July 2014 в 05:58
  • 4
    Блестящий - мне не приходило бы в голову через 100 лет, что вы можете включить файлы cookie как часть загрузки файла. Спасибо!! – freefaller 12 February 2015 в 09:37
  • 5
    Как указывали другие, это решение решает только часть проблемы, ожидая, что сервер подготовит время файла. Другая часть проблемы, которая может быть значительной в зависимости от размера файла и скорости соединения, - это время, необходимое для фактического получения всего файла на клиенте. И это решение не решено. – AsGoodAsItGets 29 June 2016 в 11:59

Если Xmlhttprequest с blob не является опцией, вы можете открыть файл в новом окне и проверить, не заселены ли элементы eny в этом теле окна с интервалом.

var form = document.getElementById("frmDownlaod");
 form.setAttribute("action","downoad/url");
 form.setAttribute("target","downlaod");
 var exportwindow = window.open("", "downlaod", "width=800,height=600,resizable=yes");
 form.submit();

var responseInterval = setInterval(function(){
	var winBody = exportwindow.document.body
	if(winBody.hasChildNodes()) // or 'downoad/url' === exportwindow.document.location.href
	{
		clearInterval(responseInterval);
		// do your work
		// if there is error page configured your application for failed requests, check for those dom elemets 
	}
}, 1000)
//Better if you specify maximun no of intervals

0
ответ дан aniketKumkar 28 August 2018 в 16:45
поделиться

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

Библиотека обмена сообщениями между клиентом, которую мне нравится и рекомендую, - Socket.io (через Node.js). После того, как ваш серверный сценарий будет создан, генерирующий файл, который будет передан для загрузки, ваша последняя строка в этом скрипте может передать сообщение Socket.io, которое отправляет уведомление клиенту. На клиенте Socket.io прослушивает входящие сообщения, исходящие от сервера, и позволяет вам действовать на них. Преимущество использования этого метода над другими заключается в том, что вы можете обнаружить «истинное» финишное событие после завершения потоковой передачи.

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

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

Socket.io невероятно прост в установке и использовании. Подробнее: http://socket.io/

2
ответ дан Art Geigel 28 August 2018 в 16:45
поделиться

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

2
ответ дан bluish 28 August 2018 в 16:45
поделиться
  • 1
    Я должен уточнить - я не слишком обеспокоен тем, когда загрузка завершается . Если я могу просто определить, когда начнется загрузка, этого будет достаточно. – JW. 9 July 2009 в 21:55

старый поток, я знаю ...

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

скрипт, который обрабатывает (моя проблема: получение файлов через http и доставка их как zip), пишет статус сессии.

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

страница загрузки:

    <a href="download.php?id=1" class="download">DOWNLOAD 1</a>
    <a href="download.php?id=2" class="download">DOWNLOAD 2</a>
    ...
    <div id="wait">
    Please wait...
    <div id="statusmessage"></div>
    </div>
    <script>
//this is jquery
    $('a.download').each(function()
       {
        $(this).click(
             function(){
               $('#statusmessage').html('prepare loading...');
               $('#wait').show();
               setTimeout('getstatus()', 1000);
             }
          );
        });
    });
    function getstatus(){
      $.ajax({
          url: "/getstatus.php",
          type: "POST",
          dataType: 'json',
          success: function(data) {
            $('#statusmessage').html(data.message);
            if(data.status=="pending")
              setTimeout('getstatus()', 1000);
            else
              $('#wait').hide();
          }
      });
    }
    </script>

getstatus.php

<?php
session_start();
echo json_encode($_SESSION['downloadstatus']);
?>

download.php

    <?php
    session_start();
    $processing=true;
    while($processing){
      $_SESSION['downloadstatus']=array("status"=>"pending","message"=>"Processing".$someinfo);
      session_write_close();
      $processing=do_what_has_2Bdone();
      session_start();
    }
      $_SESSION['downloadstatus']=array("status"=>"finished","message"=>"Done");
//and spit the generated file to the browser
    ?>
11
ответ дан bytepirate 28 August 2018 в 16:45
поделиться
  • 1
    но если у пользователя открыто несколько окон или загрузок? также вы получаете избыточный вызов на сервер – Yuki 18 July 2011 в 15:30
  • 2
    Если у вас есть несколько подключений от одного пользователя, они будут ждать завершения других подключений, поскольку session_start () блокирует сеанс для пользователя и запрещает доступ ко всем другим процессам. – Honza Kuchař 18 December 2014 в 13:29
  • 3
    вам не нужно использовать .each() для регистрации событий. просто скажите $('a.download').click() – robisrob 16 November 2015 в 23:26

Я написал простой класс JavaScript, который реализует технику, аналогичную той, которая описана в ht-файле answer . Надеюсь, это может быть полезно кому-то здесь. Проект GitHub называется response-monitor.js

По умолчанию он использует spin.js в качестве индикатора ожидания, но также предоставляет набор обратных вызовов для реализации пользовательского индикатора.

JQuery поддерживается, но не требуется.

Известные функции

  • Простая интеграция
  • Нет зависимые
  • Плагин JQuery (необязательно)
  • Spin.js Интеграция (опционально)
  • Конфигурируемые обратные вызовы для мониторинга событий
  • одновременные запросы
  • Обнаружение сбоев на стороне сервера
  • Обнаружение тайм-аута
  • Кросс-браузер

Пример использования

HTML

<!-- the response monitor implementation -->
<script src="response-monitor.js"></script>

<!-- optional JQuery plug-in -->
<script src="response-monitor.jquery.js"></script> 

<a class="my_anchors" href="/report?criteria1=a&criteria2=b#30">Link 1 (Timeout: 30s)</a>
<a class="my_anchors" href="/report?criteria1=b&criteria2=d#10">Link 2 (Timeout: 10s)</a>

<form id="my_form" method="POST">
    <input type="text" name="criteria1">
    <input type="text" name="criteria2">
    <input type="submit" value="Download Report">
</form>

Клиент (обычный JavaScript)

//registering multiple anchors at once
var my_anchors = document.getElementsByClassName('my_anchors');
ResponseMonitor.register(my_anchors); //clicking on the links initiates monitoring

//registering a single form
var my_form = document.getElementById('my_form');
ResponseMonitor.register(my_form); //the submit event will be intercepted and monitored

Клиент (JQuery)

$('.my_anchors').ResponseMonitor();
$('#my_form').ResponseMonitor({timeout: 20});

Клиент с обратными вызовами (JQuery)

//when options are defined, the default spin.js integration is bypassed
var options = {
    onRequest: function(token){
        $('#cookie').html(token);
        $('#outcome').html('');
        $('#duration').html(''); 
    },
    onMonitor: function(countdown){
        $('#duration').html(countdown); 
    },
    onResponse: function(status){
        $('#outcome').html(status==1?'success':'failure');
    },
    onTimeout: function(){
        $('#outcome').html('timeout');
    }
};

//monitor all anchors in the document
$('a').ResponseMonitor(options);

Сервер (PHP)

$cookiePrefix = 'response-monitor'; //must match the one set on the client options
$tokenValue = $_GET[$cookiePrefix];
$cookieName = $cookiePrefix.'_'.$tokenValue; //ex: response-monitor_1419642741528

//this value is passed to the client through the ResponseMonitor.onResponse callback
$cookieValue = 1; //for ex, "1" can interpret as success and "0" as failure

setcookie(
    $cookieName,
    $cookieValue,
    time()+300,            // expire in 5 minutes
    "/",
    $_SERVER["HTTP_HOST"],
    true,
    false
);

header('Content-Type: text/plain');
header("Content-Disposition: attachment; filename=\"Response.txt\"");

sleep(5); //simulate whatever delays the response
print_r($_REQUEST); //dump the request in the text file

Для получения дополнительных примеров проверьте папку examples в репозитории.

7
ответ дан Community 28 August 2018 в 16:45
поделиться

Очень простое (и хромое) однострочное решение - использовать событие window.onblur() для закрытия диалогового окна загрузки. Конечно, если это займет слишком много времени, и пользователь решает сделать что-то еще (например, читать электронные письма), диалог загрузки будет закрыт.

27
ответ дан Echilon 28 August 2018 в 16:45
поделиться
  • 1
    Это простой подход, который идеально подходит для избавления от загружаемого наложения для загрузки файла, который был вызван с помощью onbeforeunload. Спасибо. – wf4 14 February 2014 в 18:13
  • 2
    Это не работает во всех браузерах (некоторые из них не оставляют / размывают текущее окно как часть рабочего процесса загрузки, например Safari, некоторые версии IE и т. Д.). – hiattp 3 June 2014 в 00:15
  • 3
    Chrome и другие подобные браузеры автоматически загружают файлы, в которых это условие не выполняется. – Lucky 9 December 2015 в 13:14
  • 4
    @ Lucky, только по умолчанию. Вполне возможно, что пользователь Chrome определит, где следует сохранять загрузки, и, следовательно, см. Диалоговое окно – Edmund Reed 21 November 2016 в 11:48
  • 5
    плохая идея, потому что вы активируете размытие при изменении табуляции или любое действие за пределами окна – Michael Lane 20 March 2017 в 19:40

Я использую следующее, чтобы загрузить blobs и аннулировать URL-адрес объекта после загрузки. он работает в chrome и firefox!

function download(blob){
    var url = URL.createObjectURL(blob);
    console.log('create ' + url);

    window.addEventListener('focus', window_focus, false);
    function window_focus(){
        window.removeEventListener('focus', window_focus, false);                   
        URL.revokeObjectURL(url);
        console.log('revoke ' + url);
    }
    location.href = url;
}

после того, как диалоговое окно загрузки файла закрыто, окно возвращает ее фокус назад, так что событие фокусировки запускается.

11
ответ дан Elmer 28 August 2018 в 16:45
поделиться
  • 1
    Все еще есть проблема переключения окна и возвращения, которое заставит модальное скрыть. – dudeNumber4 22 January 2015 в 23:59
  • 2
    Браузеры, такие как Chrome, которые загружаются в нижний лоток, никогда не размывают / не переориентируют окно. – Coleman 9 June 2015 в 01:34

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

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

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

3
ответ дан gahooa 28 August 2018 в 16:45
поделиться
  • 1
    Это звучит как подход временного файла, о котором я упоминал выше. Я мог бы сделать что-то подобное, если окажется, что моя идея невозможна, но я надеялся избежать этого. – JW. 9 July 2009 в 23:01

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

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>';

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

2
ответ дан grom 28 August 2018 в 16:45
поделиться

Основываясь на примере Элмера, я подготовил собственное решение. После того, как элементы щелкнули с определенным классом download , он позволяет отображать на экране пользовательские сообщения. Я использовал триггер focus , чтобы скрыть сообщение.

JavaScript

$(function(){$('.download').click(function() { ShowDownloadMessage(); }); })

function ShowDownloadMessage()
{
     $('#message-text').text('your report is creating, please wait...');
     $('#message').show();
     window.addEventListener('focus', HideDownloadMessage, false);
}

function HideDownloadMessage(){
    window.removeEventListener('focus', HideDownloadMessage, false);                   
    $('#message').hide();
}

HTML

<div id="message" style="display: none">
    <div id="message-screen-mask" class="ui-widget-overlay ui-front"></div>
    <div id="message-text" class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ui-draggable ui-resizable waitmessage">please wait...</div>
</div>

Теперь вы должны реализовать любой элемент для загрузки:

<a class="download" href="file://www.ocelot.com.pl/prepare-report">Download report</a>

или

<input class="download" type="submit" value="Download" name="actionType">

После каждого нажатия download вы увидите сообщение, которое создает ваш отчет, подождите. ..

4
ответ дан Jerzy Gebler 28 August 2018 в 16:45
поделиться
  • 1
    Что делать, если пользователь нажимает на окно? – Tom Roggero 30 January 2015 в 00:36

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

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

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

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

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
ответ дан MarcLawrence 28 August 2018 в 16:45
поделиться

Быстрое решение, если вы хотите отображать сообщение или gif загрузчика до тех пор, пока не отобразится диалоговое окно загрузки, следует поместить сообщение в скрытый контейнер, и когда вы нажимаете кнопку, которая генерирует загружаемый файл, вы делаете контейнер видимый. Затем используйте jquery или javascript, чтобы поймать событие фокуса кнопки, чтобы скрыть контейнер, содержащий сообщение

0
ответ дан Mihaela Rada 28 August 2018 в 16:45
поделиться

Создайте iframe при нажатии кнопки / ссылки и добавьте это в тело.

                  $('<iframe />')
                 .attr('src', url)
                 .attr('id','iframe_download_report')
                 .hide()
                 .appendTo('body'); 

Создайте iframe с задержкой и удалите его после загрузки.

                            var triggerDelay =   100;
                            var cleaningDelay =  20000;
                            var that = this;
                            setTimeout(function() {
                                var frame = $('<iframe style="width:1px; height:1px;" class="multi-download-frame"></iframe>');
                                frame.attr('src', url+"?"+ "Content-Disposition: attachment ; filename="+that.model.get('fileName'));
                                $(ev.target).after(frame);
                                setTimeout(function() {
                                    frame.remove();
                                }, cleaningDelay);
                            }, triggerDelay);
-2
ответ дан Pir Abdul 28 August 2018 в 16:45
поделиться
  • 1
    Это отсутствие информации, и она не решает проблему «когда скрывать загрузку». вопрос. – Tom Roggero 30 January 2015 в 00:38

Я очень опаздываю на вечеринку, но я расскажу об этом здесь, если кто-нибудь еще захочет узнать мое решение:

У меня была настоящая борьба с этой точной проблемой, но я нашел жизнеспособную

У меня была html-страница, которая запустила отдельный php-скрипт, который сгенерировал файл, а затем загрузил его. На html-странице я использовал следующий jquery в заголовке html (вам также нужно включить библиотеку jquery):

<script>
    $(function(){
        var iframe = $("<iframe>", {name: 'iframe', id: 'iframe',}).appendTo("body").hide();
        $('#click').on('click', function(){
            $('#iframe').attr('src', 'your_download_script.php');
        });
        $('iframe').load(function(){
            $('#iframe').attr('src', 'your_download_script.php?download=yes'); <!--on first iframe load, run script again but download file instead-->
            $('#iframe').unbind(); <!--unbinds the iframe. Helps prevent against infinite recursion if the script returns valid html (such as echoing out exceptions) -->
        });
    });
</script>

На вашем_download_script.php есть следующее:

function downloadFile($file_path) {
    if (file_exists($file_path)) {
        header('Content-Description: File Transfer');
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename=' . basename($file_path));
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file_path));
        ob_clean();
        flush();
        readfile($file_path);
        exit();
    }
}


$_SESSION['your_file'] = path_to_file; //this is just how I chose to store the filepath

if (isset($_REQUEST['download']) && $_REQUEST['download'] == 'yes') {
    downloadFile($_SESSION['your_file']);
} else {
    *execute logic to create the file*
}

Чтобы прервать это, jquery сначала запускает ваш php-скрипт в iframe. Iframe загружается после создания файла. Затем jquery снова запускает скрипт с переменной запроса, сообщающей скрипту для загрузки файла.

Причина, по которой вы не можете выполнить загрузку и создание файлов за один раз, связана с заголовком php () функция. Если вы используете header (), вы меняете скрипт на что-то другое, кроме веб-страницы, и jquery никогда не распознает сценарий загрузки как «загруженный». Я знаю, что это может не обязательно обнаруживать, когда браузер получает файл, но ваша проблема была похожа на мою.

3
ответ дан Walker Boh 28 August 2018 в 16:45
поделиться
Другие вопросы по тегам:

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