SORU
18 NİSAN 2013, PERŞEMBE


Ajax post üzerinden dosya indirme kolu

Belirli bir URL için ajax POST isteği gönderen bir javascript uygulaması var. Yanıt JSON dize olabilir veya bir dosya (ek olarak) olabilir. Kolayca İçerik Türünü tespit etmek ve-Disposition İçerik ajax hakkımı kullanabilirim, ama bir yanıt dosyası içerdiğini tespit bir kez, nasıl müşteri indirmek için teklif yapabilir miyim? Benzer konular burada çok sayıda okudum ama hiçbiri aradığım cevabı verecektir.

Lütfen, lütfen, lütfen cevap bunun için ajax kullanmak gerektiğini, yoksa bütün bunların bir seçenek olduğu için tarayıcı yönlendirir, gerektiğini telkin göndermeyin. Düz HTML bir form kullanmak da bir seçenek değil. İstediğim şey bir indirme istemci için iletişim göstermektir. Bu yapılabilir ve nasıl?

DÜZENLEME:

Görünüşe göre, bu yapılamaz, ama kabul cevabı önerdiği gibi basit bir çözüm var. Gelecekte bu sorun genelinde gelir herkes için, burada çözdüm:

$.ajax({
    type: "POST",
    url: url,
    data: params,
    success: function(response, status, request) {
        var disp = request.getResponseHeader('Content-Disposition');
        if (disp && disp.search('attachment') != -1) {
            var form = $('<form method="POST" action="'   url   '">');
            $.each(params, function(k, v) {
                form.append($('<input type="hidden" name="'   k  
                        '" value="'   v   '">'));
            });
            $('body').append(form);
            form.submit();
        }
    }
});

Yani temelde, sadece AJAX isteğinde kullanılan aynı parametreler ile HTML bir form oluşturmak ve göndermek.

CEVAP
22 Mayıs 2014, PERŞEMBE


Bu (modern tarayıcılarda) FileAPİ parçaları kullanılarak yapılabilir çünkü bu kadar çabuk pes etmeyin:

Edit: jQuery ajax ikili yanıtları ele alamaz düzgün (responseType set yok), daha sade XMLHttpRequest bir telefon kullanın.

var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
    if (this.status === 200) {
        var filename = "";
        var disposition = xhr.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }
        var type = xhr.getResponseHeader('Content-Type');

        var blob = new Blob([this.response], { type: type });
        if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
            window.navigator.msSaveBlob(blob, filename);
        } else {
            var URL = window.URL || window.webkitURL;
            var downloadUrl = URL.createObjectURL(blob);

            if (filename) {
                // use HTML5 a[download] attribute to specify filename
                var a = document.createElement("a");
                // safari doesn't support this yet
                if (typeof a.download === 'undefined') {
                    window.location = downloadUrl;
                } else {
                    a.href = downloadUrl;
                    a.download = filename;
                    document.body.appendChild(a);
                    a.click();
                }
            } else {
                window.location = downloadUrl;
            }

            setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
        }
    }
};
xhr.send($.param(params));

Burada eski sürüm jQuery kullanarak.ajax. Yanıt bazı karakter bir dize ikili veri bozmayı olabilir.

$.ajax({
    type: "POST",
    url: url,
    data: params,
    success: function(response, status, xhr) {
        // check for a filename
        var filename = "";
        var disposition = xhr.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }

        var type = xhr.getResponseHeader('Content-Type');
        var blob = new Blob([response], { type: type });

        if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
            window.navigator.msSaveBlob(blob, filename);
        } else {
            var URL = window.URL || window.webkitURL;
            var downloadUrl = URL.createObjectURL(blob);

            if (filename) {
                // use HTML5 a[download] attribute to specify filename
                var a = document.createElement("a");
                // safari doesn't support this yet
                if (typeof a.download === 'undefined') {
                    window.location = downloadUrl;
                } else {
                    a.href = downloadUrl;
                    a.download = filename;
                    document.body.appendChild(a);
                    a.click();
                }
            } else {
                window.location = downloadUrl;
            }

            setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
        }
    }
});

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jeb Corliss

    Jeb Corliss

    17 Kasım 2006
  • Sean Murphy

    Sean Murphy

    4 ŞUBAT 2009
  • Simon Hayter

    Simon Hayter

    20 HAZİRAN 2010