Extjs 4通过ajax调用下载文件

时间:2013-12-10 16:33:41

标签: ajax extjs download tornado

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

        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()

服务器端代码似乎工作正常,但客户端(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");
    }});

7 个答案:

答案 0 :(得分:9)

在阅读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);

}

答案 1 :(得分:5)

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

制作标准的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
    }
});

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

答案 2 :(得分:2)

我认为你可以采取更容易的解决方案。忘记ajax,只需让普通的旧js为你打开文件:

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

这将打开一个新标签并从那里开始下载。

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

我只需要宣传ajax请求的成功功能:

window.open('urltothefile.ext')

答案 5 :(得分:0)

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

像这样使用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
        }
    });
}

extjs forum

复制答案

选项: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
        }
    });
}

答案 6 :(得分:0)

您无法使用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);

};

用法:

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

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