【问题标题】:Download pushed file using JavaScript使用 JavaScript 下载推送的文件
【发布时间】:2013-12-02 19:46:14
【问题描述】:

可能,这个问题听起来已经回答并且可以通过谷歌搜索,但我没能找到答案。

我将 WebApi 安装为支持 SignalR 的 Windows 服务。经过一些操作,我尝试将 *.zip 文件推送给客户端:

using (var zip = new ZipFile())
{
   zip.AddDirectory(mydir);
   Clients.All.pushFile(zip,"application/zip, application/octet-stream",myname);
}

我有几个客户端:C# WinForms 应用程序和带有 JavaScript 的 HTML 页面。 我尝试使用FileSaver.js 处理此方法,但似乎它不支持 zip 或我做错了什么:

pushFile: function (result, type, name) {
            try {
                var blob = new Blob(result, type);
                saveAs(blob, name);
            } catch(e) {
                alert(e);
            }
        }

那么问题是 - 如何使用 JavaScript 客户端处理我的 SignalR 文件推送?我想要一个保存文件对话框。 如果这个问题已经得到解答,请分享链接并接受我对重复的道歉!谢谢!

【问题讨论】:

  • pushFile 在 js 中被调用?你能检查一下 Firebug 收到的内容吗?
  • 是的,确实如此。我收到一个对象。 prntscr.com/257lhv

标签: c# javascript asp.net-web-api signalr


【解决方案1】:

这是一种解决方法,直到您找出 filesaver.js 不起作用的原因: 我相信你使用这个 ZipFile:http://dotnetzip.herobo.com/DNZHelp/html/8b981f77-742a-5f47-6299-c27104871d8c.htm

在 C# 中:

     //SignalR
         string zipName = "myZip"
         Clients.All.pushFileNotification("Download.aspx?myZip=" + zipName);

     //Download.aspx
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!string.IsNullOrWhiteSpace(Request["myZip"]))
        {
            download(Request["myZip"]);
        }
     }

    private void download(string myZip)
    {
        Response.Clear();
        if (myZip == "myZip") // some validation if you want
        {                
            using (MemoryStream output = new MemoryStream())
            {
                using (var zip = new ZipFile())
                {
                    zip.AddDirectory(mydir);
                    if (Response.IsClientConnected)
                    {
                        Response.ClearHeaders();
                        Response.ClearContent();
                        zip.Save(output);
                        byte[] buffer = output.ToArray();
                        Response.AppendHeader("Content-Length", buffer.Length.ToString());
                        Response.ContentType = "application/octet-stream";
                        Response.AppendHeader("Content-Disposition", "attachment; filename=" + myZip);


                        if (buffer.Length < 1)
                        {
                            return;
                        }
                        if (Response.IsClientConnected)
                        {
                            Response.BinaryWrite(buffer);
                        }
                    }
                }
            }
        }

        Response.End();
    } 

在 html 中添加 iframe:

<iframe id="zipLoader" src="#" width="0" height="0" tabindex="-1" title="empty" hidden style="display: none;">
</iframe>

在js中:

pushFileNotification: function (result) {
        try {
             $('#zipLoader').attr('src', result);
        } catch(e) {
            alert(e);
        }
    }

它很丑,但它应该可以工作。如果它能像你写的那样工作,那就最好了。 我用的是 jQuery,但是你可以理解这里发生了什么,你可以将它替换为纯 js。

【讨论】:

  • 我的 zip 文件在服务器上没有任何路径,它是动态创建的。
  • 即便如此,有一种方法可以将其写入响应
  • 你能给出一个提示,或者更好 - 一个我的例子吗?如何将文件写入响应?
【解决方案2】:

它可能无济于事,但希望它可以让您了解如何解决您的问题。

    using (var zip = new ZipFile())
    {
        var mStream = new MemoryStream();
        byte[] fileData = ;//get file data here
        string fileName = ; // get file name here
        var memoryStream = new MemoryStream(fileData);
        memoryStream.Seek(0, SeekOrigin.Begin);
        zip.AddEntry(fileName, memoryStream);
        mStream.Seek(0, SeekOrigin.Begin);
        zip.AddDirectory(mydir);
        zip.Save(mStream);
        mStream.Position = 0;

         Clients.All.pushFile(mStream,"application/zip, application/octet-stream");
    }

【讨论】:

  • 谢谢!将文件写入流并将其传递给 FileSaver 就可以了,现在它可以工作了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2021-12-18
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多