ajax - Extjs 4(下面有3.4的代码)下载从post请求返回的文件

标签 ajax extjs extjs4 download http-post

我看到了与此略有相关的问题,但没有一个能回答我的问题。我设置了一个 Ext.Ajax.request,如下所示:

var paramsStringVar = 'param1=1&param2=two&param3=something&param4=etc';

Ext.Ajax.request({
  url: '/cgi-bin/url.pl',
  method:'POST',
  params:paramsStringVar,
  timeout:120000,
  success: function(response, opts){
    var objhtml = response.responseText; //content returned from server side
    console.log(objhtml);
  }

});

此请求从后端检索适当的内容。一个参数是outputType,它可以取值{html, excel, csv}。当返回 html 来显示时,我能够正确处理和显示它。现在来解决这个问题...

当我将 outputType 参数设置为 csv 或 excel 时,我会根据请求返回 csv 或 tsv(excel) 形式的适当内容。但是,我不需要内容,我想要提示下载文件(csv 或 excel)。如何让浏览器自动提示用户下载文件,而不是仅仅检索 extjs 中的文本内容?

版本 4.07,因此我无法使用任何 4.1 独有的功能

最佳答案

似乎没有万无一失的解决方案,但我会尝试几种方法:

1) 使用 iframe而不是真正的 XHR 将数据 POST 到服务器,例如<form action="/something" target="myiframe">哪里myiframename隐藏的 iframe 的。这样,您的表单将使用 iframe(而不是您的主窗口)将数据提交到配置的 URL。您的服务器应将响应 header 设置为 application/octet-stream (或二进制数据的某种 MIME 类型),以便浏览器触发下载。否则(如果在您的情况下返回 html),您可以只检索 iframe 的 body insideHTML 并将其显示在 UI 中的用户。虽然使用 iframe(或新窗口)而不是 XHR 听起来不是最好的主意,但此解决方案似乎是迄今为止最可靠的(并且具有最佳的浏览器支持)。

这是一个稍微修改过的例子 Ext.form.Basic文档页面:

Ext.create('Ext.form.Panel', {
    title: 'Basic Form',
    renderTo: Ext.getBody(),
    width: 350,

    // Any configuration items here will be automatically passed along to
    // the Ext.form.Basic instance when it gets created.

    // *THIS* makes the form use a standard submit mechanism, not XHR
/**/standardSubmit: true,

    // URL to submit to
    url: 'save-form.php',

    items: [{
        fieldLabel: 'Field',
        xtype: 'textfield',
        name: 'theField'
    }],

    buttons: [{
        text: 'Submit',
        handler: function() {
            // The getForm() method returns the Ext.form.Basic instance:
            var form = this.up('form').getForm();
            if (form.isValid()) {
                // Submit the Ajax request and handle the response
                form.submit({
                    success: function(form, action) {
                       Ext.Msg.alert('Success', action.result.msg);
                    },
                    failure: function(form, action) {
                        Ext.Msg.alert('Failed', action.result.msg);
                    },

                    // You can put the name of your iframe here instead of _blank
                    // this parameter makes its way to Ext.form.Basic.doAction() 
                    // and further leads to creation of StandardSubmit action instance
/**/                target: '_blank'                        
                });
            }
        }
    }]
});

这里有两个关键参数(标有 /**/ 的行):

  1. standardSubmit: true您传递给表单的配置将使其执行标准提交而不是 XHR。
  2. 通过 target表单的 submit 操作的参数。此功能没有记录,但您可以在 Ext.form.action.Submit 中看到它的使用。源代码(传递给 Ext.form.Basic.submit() 方法的所有选项最终都会作为 Ext.form.action.* 实例的参数。

在示例代码中我输入 target: '_blank'证明它可以立即工作(将创建一个新的浏览器窗口)。您可以稍后将其替换为 iframe 的名称,但我建议您首先测试表单如何将数据提交到常规新窗口,然后开发创建和处理 iframe 的逻辑。你必须自己在 iframe 内处理结果,我想。没那么难,看Ext.data.Connection.upload()实现作为 iframe 处理的示例。

ExtJS实际上已经使用了iframe文件上传技术。请参阅Ext.data.ConnectionExt.form.field.Field.isFileUpload()了解它如何工作。

2) 此处建议:Using HTML5/Javascript to generate and save a file

如果您不想采用 iframe 方式,可以尝试从响应数据生成数据 URI 并导航到该 URI 触发下载:

content = "Hello world!";
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
window.location.href = uriContent;

同样,mimetype 在这里至关重要。这对我有用,但是您应该注意,浏览器对数据 URI 施加了大小限制(256Kb 是一个安全的选择)。

3) 上述线程中的另一个答案链接到 FileSaver.js库实现了(废弃?)w3 规范。使用与演示 here 。它使用 [BlobBuilder] 生成二进制数据 blob,该数据进一步用于使用多种方法之一初始化下载。虽然此解决方案似乎有效,但它使用已弃用的 API,并且可能无法面向 future 。

关于ajax - Extjs 4(下面有3.4的代码)下载从post请求返回的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782856/

相关文章:

javascript - 如何自定义actionSheet和actionSheet按钮的extjs大小?

javascript - ExtJS - 堆积条形图条件着色

javascript - 使用 AJAX 时阻止跨域请求

extjs - 如何在extjs中为组合框添加不带冒号的fieldLabel

ExtJs 和嵌套模型

javascript - ExtJS:存储加载,记录在表单中但不在字段中

javascript - 使用 Node js 将 mp3 保存为 ajax post 数据

javascript - 使用 Ajax 在同一个 PHP 文件 (JSON) 中进行 POST 和 GET

ajax - 将 jQuery ajax 调用包装在变量中,以便我可以在需要时设置Timeout 和clearTimeout?

javascript - 如何根据我在 extjs 中选择的文件设置窗口的标题