使用POST请求而不是GET下载文件

时间:2011-01-23 09:54:07

标签: asp.net-mvc

我有一个ASP.NET MVC应用程序。在一个页面上,我有一个按钮,允许用户根据用户设置的页面上的某些值(滑块范围,复选框等)下载CSV文件,而无需离开页面。我的Controller类通过返回FileResult的方法返回该文件。

目前,我的javascript onClick方法实现如下,有点jQuery:

function DownloadCSV() {
    var url = <%=Action("DownloadCSV", "Controller")%> + '?' +
                  $.param({
                      SomeValue: $("#valuefromform").val(),
                      OtherValue: $("#anothervaluefromform").val(),
                      ...
                  });

    window.location = url;
}

这部分完美无缺,所以问题是:是否可以重写此方法,以便“发布”查询而不是使用“获取”查询字符串?

(我已经尝试过使用AJAX请求,它可以很好地POST,但是虽然我得到了文件数据,但这是XHR响应的一部分,我无法弄清楚如何将其下载为文件,所以如果有的话这样做的方式也很棒!)

2 个答案:

答案 0 :(得分:9)

您可以设置表单:

<% using (Html.BeginForm("DownloadCSV", "Controller", null, FormMethod.Post, new { id = "myform" })) { %>
    <input type="hidden" id="someValue" name="someValue" value="" />
    <input type="hidden" id="otherValue" name="otherValue" value="" />
<% } %>

当下载时间时,只需提交此表单:

function DownloadCSV() {
    $('#someValue').val($('#valuefromform').val());
    $('#otherValue').val($('#anothervaluefromform').val());
    $('#myform').trigger('submit');
}

另一种可能性是完全动态地构建此表单并在提交之前将其注入DOM。

答案 1 :(得分:0)

这可能不是您正在寻找的答案,但您可以通过ajax设置POST请求,就像您一直在做的那样,而不是返回文件,返回csv文件的路径和/或文件名你创造了。您的帖子操作将被修改为有一个额外的步骤,以使用唯一的名称(返回)将该csv文件保存到服务器。

然后您可以执行相同的window.location = url逻辑,然后通过XHR请求传入返回给您的文件名。

在伪代码中:

$.post(/*bunch of ajax stuff*/,
    success : function(result) { document.location = 'CSVDownloader/?filename=' + result ; }
);

其中CSVDownloader是包装下载并返回正确标头类型的人。最佳实践要求您不要打开任何可访问Web的文件夹以获得写入权限,因此我假设该文件被保存在Web服务器根目录的某处。