使用Jquery Post的Web API下载文件
本文关键字:API 下载 文件 Web Jquery Post 使用 | 更新日期: 2023-09-27 18:08:15
我有一个web Api函数返回一个文件流
[HttpPost]
public HttpResponseMessage DownloadDocument([FromBody] parameters)
{
try
{
var stream = FileHelper.GetFilesStream(fileUrl);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(stream) };
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition.FileName = fileName;
return result;
}
catch (Exception)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "File Not Found");
}
}
我如何在Jquery Ajax中调用这个方法来下载文件,以便弹出保存文件对话框。我正在使用knockout.js,在单击按钮的事件处理程序中,我调用此WebAPI方法并获得流,但我不知道如何将其保存到文件中。
不能从ajax调用中下载文件。您将需要使用get请求来下载文件。
你可以做的是使用你的ajax post如上所述,但将文件保存在数据库中,然后返回json与文档的id或url下载文档。然后你可以添加一个隐藏的iframe来下载文档。
看看这个答案,它展示了如何做到这一点:https://stackoverflow.com/a/16086443/2326610
恐怕你不能直接通过JQuery下载文件。解决这个问题的一个方法是在html:
中声明一个隐藏iframe。<iframe id='hiddenIframe' src="" style="display:none; visibility:hidden;" ></iframe>
当你点击下载按钮/链接,然后在jQuery中,你可以简单地设置iframe源:
$('#downloadButton').click(function(){
$('#hiddenIframe').attr('src', 'api/DownloadDocument');
})
你可以通过修改你向webapi发送数据的方式来解决这个问题。
在你的Javascript中,你可以创建一个隐藏的表单,并添加你需要的数据,然后提交它。示例代码以coffeescript形式呈现,但应该易于阅读/转换:
downloadDocument: (fileUri, otherProp, successCallback) =>
if $('#hidden-form').length > 0
$('#hidden-form').remove()
$('<form>').attr(
method: 'POST',
id: 'hidden-form',
action: '/your/url/to/method'
).appendTo('body');
$('<input>').attr({
type: 'hidden',
id: 'fileUri',
name: 'fileUri',
value: fileUri
}).appendTo('#hidden-form')
$('<input>').attr({
type: 'hidden',
id: 'otherProp',
name: 'otherProp',
value: otherProp
}).appendTo('#hidden-form')
$('#hidden-form').bind("submit", successCallback)
$('#hidden-form').submit()
然后我也会创建一个DTO对象,作为webAPI控制器的参数,而不是从请求体中读取:
public DownloadDocumentDTO
{
public string fileUri {get;set;}
public object otherProp {get;set;}
}
[HttpPost]
public HttpResponseMessage DownloadDocument(DownloadDocumentDTO _dto)
{
....
}
控制器方法中的代码应该是正确的。应该注意的是,如果你试图传递更复杂的数据(不知道你是否这样做,因为它没有提到),那么你将需要添加更多的输入到隐藏表单,它将无法传递对象。