1

この問題があります。合成では、クリックすると次のような Ajax リクエストを実行するダウンロード ボタンがあります。

Ext.Ajax.request({
url: 'DownloadServlet',
method: 'GET',      
});

この要求は、デフォルト ファイルを読み取るサーブレットによって処理されます。ファイルの読み込みは成功しており、実際にfirebugではGETの状態が「200」となっています。

問題は、フロントエンド (extjs) がファイルのダウンロードを管理していないように見えることです。ブラウザには、ファイルをダウンロードするための従来の詳細ウィンドウが表示されたと思います。

どうなり得るか?ありがとう

4

2 に答える 2

3

これを試して

downloadWhatever : function() {
    Ext.core.DomHelper.append(document.body, {
            tag : 'iframe',
            id : 'downloadIframe',
            frameBorder : 0,
            width : 0,
            height : 0,
            css : 'display:none;visibility:hidden;height:0px;',
            src : '/your/restful/url/'
        });
    },

サーバー側のスプリング (ご参考までに)

@RequestMapping(value = "/url", method = RequestMethod.GET)
public void download(HttpServletRequest request,
        HttpServletResponse response) throws ServletRequestBindingException, IOException {
    String tempFile = .. get your file
    File file = new File(tempFile);
            // in case you have zipped it ...
            // else set the correct ContentType
    response.setContentType("application/zip");
    response.setContentLength((int) file.length());
    response.setHeader("fileName", file.getName());
    response.setHeader("Content-Disposition", "attachment; filename="+ file.getName());

    InputStream in = new FileInputStream(file);
    OutputStream out = response.getOutputStream();
    byte[] buffer = new byte[1024];
    int read = 0;
    while ((read = in.read(buffer, 0, buffer.length)) != -1) {
        out.write(buffer, 0, read);
    }

    in.close();
    out.flush();
    out.close();
}
于 2012-10-25T16:05:03.153 に答える
1

AJAX 呼び出しでファイルをダウンロードすることはできません。基本的に、ハードとシンプルの 2 つの解決策があります。

シンプル: window.popup または document.location.href を使用して、ファイルが保存されている URL にリダイレクトするだけで、通常のブラウザの方法でダウンロードできます。application/octet-stream のように、ブラウザーがレンダリングしない MIME タイプを送信していることを確認してください。

ハード: AJAX 呼び出しでバイナリまたは base64 でエンコードされたファイル コンテンツを取得し、base64 でエンコードされた href を使用してダウンロード リンクを作成できます。Chrome では次のようになります。

<a href="base64,mime-type,...encoded trash..." download="download">

他のブラウザ用のソリューションもいくつかありますが、現在理想的には Chrome でのみ機能します。他のブラウザでは、次のようなコードを使用しています:

var showSave;

// Feature test: Does this browser support the download attribute on anchor tags? (currently only Chrome)
var DownloadAttributeSupport = 'download' in document.createElement('a');

// Use any available BlobBuilder/URL implementation:
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;

// IE 10 has a handy navigator.msSaveBlob method. Maybe other browsers will emulate that interface?
// See: http://msdn.microsoft.com/en-us/library/windows/apps/hh441122.aspx
navigator.saveBlob = navigator.saveBlob || navigator.msSaveBlob || navigator.mozSaveBlob || navigator.webkitSaveBlob;

// Anyway, HMTL5 defines a very similar but more powerful window.saveAs function:
// http://www.w3.org/TR/file-writer-api/#the-filesaver-interface
window.saveAs = window.saveAs || window.webkitSaveAs || window.mozSaveAs || window.msSaveAs;
// However, this is not supported by any browser yet. But there is a compatibility library that
// adds this function to browsers that support Blobs (except Internet Exlorer):
// http://eligrey.com/blog/post/saving-generated-files-on-the-client-side
// https://github.com/eligrey/FileSaver.js

// mime types that (potentially) don't trigger a download when opened in a browser:
var BrowserSupportedMimeTypes = {
    "image/jpeg": true,
    "image/png": true,
    "image/gif": true,
    "image/svg+xml": true,
    "image/bmp": true,
    "image/x-windows-bmp": true,
    "image/webp": true,
    "audio/wav": true,
    "audio/mpeg": true,
    "audio/webm": true,
    "audio/ogg": true,
    "video/mpeg": true,
    "video/webm": true,
    "video/ogg": true,
    "text/plain": true,
    "text/html": true,
    "text/xml": true,
    "application/xhtml+xml": true,
    "application/json": true
};

// Blobs and saveAs (or saveBlob)   :
if (BlobBuilder && (window.saveAs || navigator.saveBlob)) {
    // Currently only IE 10 supports this, but I hope other browsers will also implement the saveAs/saveBlob method eventually.
    showSave = function (data, name, mimeType) {
        var builder = new BlobBuilder();
        builder.append(data);
        var blob = builder.getBlob(mimetype||"application/octet-stream");
        if (!name) name = "Download.bin";
        // I don't assign saveAs to navigator.saveBlob (or the other way around)
        // because I cannot know at this point whether future implementations
        // require these methods to be called with 'this' assigned to window (or
        // naviagator) in order to work. E.g. console.log won't work when not called
        // with this === console.
        if (window.saveAs) {
            window.saveAs(blob, name);
        }
        else {
            navigator.saveBlob(blob, name);
        }
    };
}
else if (window.Blob && URL && window.atob) {
    // atob to base64_decode the data-URI
    showSave = function (data, name, mimetype) {
        var image_data = atob(data);
        // Use typed arrays to convert the binary data to a Blob
        var arraybuffer = new ArrayBuffer(image_data.length);
        var view = new Uint8Array(arraybuffer);
        for (var i=0; i<image_data.length; i++) {
            view[i] = image_data.charCodeAt(i) & 0xff;
        }
        var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});

        // Use the URL object to create a temporary URL
        var url = URL.createObjectURL(blob);
        //window.open(url, '_blank', '');
        document.location.href = url
    }
}
// Blobs and object URLs:
else if (BlobBuilder && URL) {
    // Currently WebKit and Gecko support BlobBuilder and object URLs.
    showSave = function (data, name, mimetype) {
        var blob, url, builder = new BlobBuilder();
        builder.append(data);
        if (!mimetype) mimetype = "application/octet-stream";
        if (DownloadAttributeSupport) {
            blob = builder.getBlob(mimetype);
            url = URL.createObjectURL(blob);
            // Currently only Chrome (since 14-dot-something) supports the download attribute for anchor elements.
            var link = document.createElement("a");
            link.setAttribute("href",url);
            link.setAttribute("download",name||"Download.bin");
            // Now I need to simulate a click on the link.
            // IE 10 has the better msSaveBlob method and older IE versions do not support the BlobBuilder interface
            // and object URLs, so we don't need the MS way to build an event object here.
            var event = document.createEvent('MouseEvents');
            event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
            link.dispatchEvent(event);
        }
        else {
            // In other browsers I open a new window with the object URL.
            // In order to trigger a download I have to use the generic binary data mime type
            // "application/octet-stream" for mime types that browsers would display otherwise.
            // Of course the browser won't show a nice file name here.
            if (BrowserSupportedMimeTypes[mimetype.split(";")[0]] === true) {
                mimetype = "application/octet-stream";
            }

            blob = builder.getBlob(mimetype);
            url = URL.createObjectURL(blob);
            //window.open(url, '_blank', '');
            document.location.href = url
        }
        // The timeout is probably not necessary, but just in case that some browser handle the click/window.open
        // asynchronously I don't revoke the object URL immediately.
        setTimeout(function () {
            URL.revokeObjectURL(url);
        }, 250);

        // Using the filesystem API (http://www.w3.org/TR/file-system-api/) you could do something very similar.
        // However, I think this is only supported by Chrome right now and it is much more complicated than this
        // solution. And chrome supports the download attribute anyway.
    };
}
// data:-URLs:
else if (!/\bMSIE\b/.test(navigator.userAgent)) {
    // IE does not support URLs longer than 2048 characters (actually bytes), so it is useless for data:-URLs.
    // Also it seems not to support window.open in combination with data:-URLs at all.
    showSave = function (data, name, mimetype) {
        if (!mimetype) mimetype = "application/octet-stream";
        // Again I need to filter the mime type so a download is forced.
        if (BrowserSupportedMimeTypes[mimetype.split(";")[0]] === true) {
            mimetype = "application/octet-stream";
        }
        // Note that encodeURIComponent produces UTF-8 encoded text. The mime type should contain
        // the charset=UTF-8 parameter. In case you don't want the data to be encoded as UTF-8
        // you could use escape(data) instead.
        window.open("data:"+mimetype+";base64,"+data, '_blank', '');
    };
}
// Internet Explorer before version 10 does not support any of the methods above.
// If it is text data you could show it in an textarea and tell the user to copy it into a text file.

更新: Flash を使用しても問題ない場合は、Chrome 以外のブラウザーの代替ソリューションを次に示します: https://github.com/dcneiner/Downloadify

于 2012-10-24T23:45:04.300 に答える