ajax Extjs 4 通过ajax调用下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20499959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:22:57  来源:igfitidea点击:

Extjs 4 downloading a file through ajax call

ajaxextjsdownloadtornado

提问by softwareplay

The problem is very simple: i have to download a file when i submit a form, it's an ajax call when the form is submitted which lets me build a file with the data taken from the form, server side, and then send it as a link to an alert. The fact is that my boss want the file to be downloaded directly and not through a link in an alert. So i had to make sure that the file is available server side through tornado(web):

问题很简单:当我提交表单时,我必须下载一个文件,提交表单时这是一个 ajax 调用,它允许我使用从表单、服务器端获取的数据构建一个文件,然后将其作为链接到警报。事实是,我的老板希望直接下载文件,而不是通过警报中的链接下载。所以我必须通过 tornado(web) 确保该文件在服务器端可用:

        self.set_header('Content-Type', 'application/octet-stream')
        self.set_header('Content-Disposition', 'attachment; filename=clients_counter.zip')
        with open("static/clients_counter.zip", 'r') as f:
            while True:
                data = f.read()
                if not data:
                    break
        self.write(data)
        self.finish()

The server side code seems to work fine, but the client side (extjs4.1) is really a nightmare. This is how my ajax call looks like now, and it doesn't work:

服务器端代码似乎工作正常,但客户端(extjs4.1)确实是一场噩梦。这就是我的 ajax 调用现在的样子,但它不起作用:

Ext.Ajax.request({
method : "GET",
url : 'http://whatever.com/count?client='+client+'&start='+start+'&end='+end,
timeout : 30000,
success :
         function (response) {
    //Ext.Msg.alert(response.responseText);
            desktop.getWindow('count-win').doClose();
            return response;
       }//handler,
     failure : 
     function(response) {
    alert("Wrong request");
    }});

回答by sakadas

After reading on various sources from Ext JS forum and here in stackoverflow, below is the approach I've chosen (using Ext JS version 4.2.1):

在阅读了来自 Ext JS 论坛和这里的 stackoverflow 的各种来源之后,下面是我选择的方法(使用 Ext JS 4.2.1 版):

downloadFile: function(config){
    config = config || {};
    var url = config.url,
        method = config.method || 'POST',// Either GET or POST. Default is POST.
        params = config.params || {};

    // Create form panel. It contains a basic form that we need for the file download.
    var form = Ext.create('Ext.form.Panel', {
        standardSubmit: true,
        url: url,
        method: method
    });

    // Call the submit to begin the file download.
    form.submit({
        target: '_blank', // Avoids leaving the page. 
        params: params
    });

    // Clean-up the form after 100 milliseconds.
    // Once the submit is called, the browser does not care anymore with the form object.
    Ext.defer(function(){
        form.close();
    }, 100);

}

回答by code4jhon

I had a similar problem trying to download an Excel File in an Ajax call I solved it this way:

我在尝试在 Ajax 调用中下载 Excel 文件时遇到了类似的问题,我是这样解决的:

Make a standard sumbit instead of Ajax.

使用标准 sumbit 代替 Ajax。

var form = Ext.create('Ext.form.Panel', { // this wolud be your form 
    standardSubmit: true,         // this is the important part 
    url: '../ObtenerArchivoAdjuntoServlet' 
});

form.submit({
    params: {
       nombreArchivo: nombreArchivo
    }
});

After this you would be able return the desired file.

在此之后,您将能够返回所需的文件。

回答by Kyle Fransham

I think you can take a much easier solution. Forget about the ajax, and just get plain old js to open the file for you:

我认为您可以采取更简单的解决方案。忘记 ajax,只需获取普通的旧 js 即可为您打开文件:

window.open('http://whatever.com/count?client='+client+'&start='+start+'&end='+end)

This will open a new tab and start the download from there.

这将打开一个新选项卡并从那里开始下载。

回答by John

After extracting/reading many posts, I managed to get this simple method to work..

在提取/阅读了许多帖子后,我设法让这个简单的方法起作用了..

                Ext.create('Ext.form.Panel', {
                    renderTo: Ext.getBody(),
                    standardSubmit: true,
                    url: 'URL'
                }).submit({params: {'PARAM1': param1, 'PARAM2': param2}});

回答by Sudhakar

The following code used to download the file using extjs 5 or 6. Add the following code to method and invoke this for button action. This downloads the file directly insteadof opening in new tab.

以下代码用于使用 extjs 5 或 6 下载文件。将以下代码添加到方法并为按钮操作调用此代码。这将直接下载文件,而不是在新选项卡中打开。

use an iframe like this:

使用这样的 iframe:

/**
 * prints the file
 */
printReport: function () {
    var url = 'downloadURL';
    Ext.Ajax.request({
        url: url,
        method: 'GET',
        autoAbort: false,
        success: function(result) {
            if(result.status == 204) {
                Ext.Msg.alert('Empty Report', 'There is no data');
            } else if(result.status == 200) {
                Ext.DomHelper.append(Ext.getBody(), {
                    tag:          'iframe',
                    frameBorder:  0,
                    width:        0,
                    height:       0,
                    css:          'display:none;visibility:hidden;height:0px;',
                    src:          url
                });
            }
        },
        failure: function() {
            //failure here will automatically
            //log the user out as it should
        }
    });
}

Copied the answer from extjs forum

extjs 论坛复制答案

Option:2 If you want to open the file in new tab

选项:2 如果要在新选项卡中打开文件

    /**
 * open file in tab
 */
openReport: function () {
    var url = 'downloadURL';
    Ext.Ajax.request({
        url: url,
        method: 'GET',
        autoAbort: false,
        success: function(result) {
            if(result.status == 204) {
                Ext.Msg.alert('Empty Report', 'There is no data');
            } else if(result.status == 200) {
                var win = window.open('', '_blank');
                win.location = url;
                win.focus();
            }
        },
        failure: function() {
            //failure here will automatically
            //log the user out as it should
        }
    });
}

回答by Arun Mohan

You cannot use ajax to download file. I've implemented file downloading in extjs which is like ajax. see the blog ajaxlikefiledownload.

您不能使用 ajax 下载文件。我已经在 extjs 中实现了文件下载,就像 ajax。请参阅博客ajaxlikefiledownload

FileDownload.downloadFile = function(arguments) {

var url = arguments['url'];
var params = arguments['params'];
var successCallback = arguments['success'];
var failureCallback = arguments['failure'];

var body = Ext.getBody();

var frame = body.createChild({
tag:'iframe',
cls:'x-hidden',
id:'hiddenframe-frame',
name:'iframe'
});

var form = body.createChild({
tag:'form',
cls:'x-hidden',
id:'hiddenform-form',
action: url,
method: 'POST',
target:'iframe'
});


if (params)
{
    for (var paramName in params)
    {

        form.createChild({
            tag:'input',
            cls:'x-hidden',
            id:'hiddenform-'+paramName,
            type: 'text',
            text: params[paramName],
            target:'iframe',
            value: params[paramName],
            name: paramName
            });

    }
}

form.dom.submit();

FileDownload.isFinished(successCallback,failureCallback);

};

};

FileDownload.isFinished = function(successCallback,failureCallback) {

//Check if file is started downloading
if (Ext.util.Cookies.get('fileDownload') && Ext.util.Cookies.get('fileDownload')=='true' ) {
    //Remove cookie call success callback 
    Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
    Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
    successCallback();
    return;
} 

//Check for error / IF any error happens then frame will load with content
try {
    if(Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML.length>0){
        Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
        Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
        failureCallback();
        //Cleanup
        Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML = ""; 

        return;
    }
} 
catch (e) {
    console.log(e);
}

console.log('polling..');
// If we are here, it is not loaded. Set things up so we check   the status again in 100 milliseconds
window.setTimeout('FileDownload.isFinished('+successCallback+','+failureCallback+')', 100);

};

};

Usage :

用法 :

FileDownload.downloadFile({
  url : url,
  params : params,
  success : function(){
   //Success call back here
  },
  failure : function(){
   //Failure callbak here
  }
});

In the http response you need to add a cookie nammed fileDownload = true

在 http 响应中,您需要添加一个名为 fileDownload = true 的 cookie

回答by softwareplay

I just had to ad to the success function of the ajax request:

我只需要为 ajax 请求的成功功能添加广告:

window.open('urltothefile.ext')