如何使用ajax window.location下载文件

时间:2017-05-25 14:13:21

标签: jquery ajax asp.net-mvc azure-web-sites

我在过滤数据表的页面上有过滤器。

一个独立的按钮,可以将数据导出为ex​​cel。

我遵循了这个例子:Download Excel file via AJAX MVC

单击导出按钮时,jQuery会读取所有过滤器值并将结果传回服务器,如下所示:

 $.ajax({
        url: url,
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        data: filterData
    }).done(function (returnData) {
        if (returnData.success) {
            window.location = returnData.locationUrl;        
        }      
    });

在服务器上我有2个动作

    [HttpPost]
    public ActionResult ExportTo(SearchVm searchVm)
    {

        var data = _service.GetSearchTerm(searchVm).Take(150).ToList();

        string handle = Guid.NewGuid().ToString();
        TempData[handle] = data;
        var fileName = $"C-{handle}.xlsx";
        var locationUrl = Url.Action("Download", new { fileGuid = handle, fileName });

        var downloadUrl = Url.Action("Download");
        return Json(new { success = true, locationUrl, guid = handle, downloadUrl }, JsonRequestBehavior.AllowGet);

    }

    [HttpGet]
    public ActionResult Download(string fileGuid, string fileName)
    {
        if (TempData[fileGuid] != null)
        {
            var fileNameSafe = $"C-{fileGuid}.xlsx";
            var data = TempData[fileGuid] as List<Company>;

            using (MemoryStream ms = new MemoryStream())
            {
                GridViewExtension.WriteXlsx(GetGridSettings(fileNameSafe), data, ms);
                MVCxSpreadsheet mySpreadsheet = new MVCxSpreadsheet();
                ms.Position = 0;
                mySpreadsheet.Open("myDoc", DocumentFormat.Xlsx, () =>
                {
                    return ms;
                });
                byte[] result = mySpreadsheet.SaveCopy(DocumentFormat.Xlsx);
                DocumentManager.CloseDocument("myDoc");
                Response.Clear();
                Response.ContentType = "application/force-download";
                Response.AddHeader("content-disposition", $"attachment; filename={fileNameSafe}");
                Response.BinaryWrite(result);
                Response.End();
            }
           }
            return new EmptyResult();
        }

上面的代码可以在本地计算机上下载文件。但是,当我在服务器上生效时,单击“导出”按钮会将用户定向到URL而不是下载文件。

我无法弄清楚为什么会这样。该应用程序托管在天蓝色的Web服务上。我在本地和生产之间可以看到的唯一区别是生产有ssl。

window.location是否有任何限制?为什么它会强制浏览器在本地计算机上下载文件,但它会将用户重定向到生产链接?

我检查过chrome控制台,没有错误。

知道为什么吗?

谢谢,

1 个答案:

答案 0 :(得分:1)

- 将fileName和fileGuid返回到您的Ajax方法并连接操作URL,而不是在后端创建它,然后调用下载操作。

- 更改返回的数据:

    [HttpPost]
    public ActionResult ExportTo(SearchVm searchVm)
    {
        var data = _service.GetSearchTerm(searchVm).Take(150).ToList();
        var handle = Guid.NewGuid().ToString();
        TempData[handle] = data;
        var fileName = $"C-{handle}.xlsx";
       /// var locationUrl = Url.Action("Download", new { fileGuid = handle, fileName });
      //  var downloadUrl = Url.Action("Download");
        return Json(new { success = true, guid = handle, fileName=fileName }, JsonRequestBehavior.AllowGet);
    }

- 更改ajax完成功能:

$.ajax({
    url: url,
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: filterData
}).done(function (returnData) {
        if (returnData.success)
        {
            window.open('/download/' +returnData.guid + '/' + returnData.fileName, '_blank', '');
        }
    });