我有一个javascript应用程序,它将ajax POST请求发送到某个URL.响应可能是JSON字符串,也可能是文件(作为附件).我可以在我的ajax调用中轻松检测Content-Type和Content-Disposition,但是一旦我检测到响应包含文件,我该如何让客户端下载它?我在这里读过很多类似的帖子,但没有一个提供我正在寻找的答案.
请,请不要发布答案,建议我不应该使用ajax或者我应该重定向浏览器,因为这都不是一个选项.使用纯HTML表单也不是一种选择.我需要的是向客户端显示下载对话框.可以这样做,怎么做?
编辑:
显然,这不可能做到,但有一个简单的解决方法,如接受的答案所示.对于今后遇到这个问题的人来说,我的解决方法如下:
__PRE__
所以基本上,只需生成一个HTML表单,其中包含与AJAX请求中使用的相同的参数并提交它.
我正在使用ASP.NET MVC的新的WebAPI的网络服务,将成为了二进制文件,主要是.cab和.exe文件.
以下控制器方法似乎有效,这意味着它返回一个文件,但它将内容类型设置为application/json:
public HttpResponseMessage<Stream> Post(string version, string environment, string filetype)
{
var path = @"C:\Temp\test.exe";
var stream = new FileStream(path, FileMode.Open);
return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream"));
}
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?
我已经告诉过我应该使用FileResult来允许用户从我的Asp.Net MVC应用程序下载文件.但我能找到的唯一例子总是与图像文件有关(指定内容类型image/jpeg).
但是,如果我不知道文件类型怎么办?我希望用户能够从我网站的文件区下载几乎任何文件.
我已经阅读了一个这样做的方法(参见前面的代码文章),实际上工作正常,除了一件事:"另存为"对话框中出现的文件名与带有下划线的文件路径连接在一起( folder_folder_file.ext).此外,似乎人们认为我应该返回一个FileResult而不是使用我找到BinaryContentResult的自定义类.
有人知道在MVC中进行这种下载的"正确"方式吗?
编辑:我得到了答案(下面),但我想如果其他人感兴趣我应该发布完整的工作代码:
public ActionResult Download(string filePath, string fileName)
{
string fullName = Path.Combine(GetBaseDir(), filePath, fileName);
byte[] fileBytes = GetFile(fullName);
return File(
fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
byte[] GetFile(string s)
{
System.IO.FileStream fs = System.IO.File.OpenRead(s);
byte[] data = new byte[fs.Length];
int br = fs.Read(data, 0, data.Length);
if (br != fs.Length)
throw new System.IO.IOException(s);
return data;
}
Run Code Online (Sandbox Code Playgroud)