提示文件下载

IT技术 javascript c# jquery reactjs asp.net-web-api2
2021-03-30 22:06:21

我的页面上有一个链接,我正在尝试生成一个 PDF 文档,然后在浏览器上显示“打开 - 保存”提示。

我的 HTML(reactjs 组件)具有以下代码,其中onclick调用_getMyDocument函数,然后调用 Webapi 方法。

 <div className="row">
     <a href="#" onClick={this._getMyDocument.bind(this)}>Test Link</a>
 </div>  

_getMyDocument(e) {
            GetMyDocument(this.props.mydata).then(()=> {
   }).catch(error=> {

  });

我的控制器有以下代码

[HttpPost]
[Route("Generate/Report")]
public IHttpActionResult GetMyReport(MyData myData)
 {  
    byte[] myDoc = MyBusinessObject.GenerateMyReport(myData);
    var result = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new ByteArrayContent(myDoc)
        };
        result.Content.Headers.ContentDisposition =
            new ContentDispositionHeaderValue("attachment")
            {
                FileName = "MyDocument.pdf"
            };
        result.Content.Headers.ContentType =
            new MediaTypeHeaderValue("application/octet-stream");

        var response = ResponseMessage(result);

        return response;
  }

目前所有代码都执行,但我没有收到文件 PDF 下载提示。我在这里做错了什么?

ajax 调用成功时的响应对象如下所示

在此处输入图片说明

5个回答

您的服务器响应看起来不错。缺少的部分是您没有以正确的方式处理来自客户端的此响应。

让我们假设您的资源 url 对象在 js 中如下所示。(即你已经知道资源url,如果你还不知道,那么你需要单独调用服务器才能知道下载url)

response.downloadUrl = app/media/fileId/document.pdf

你需要做的就是设置,

window.location = item.downloadUrl;

这将导致浏览器向服务器请求资源,来自服务器的响应必须包含Content-Disposition:attachment;. 它会导致浏览器显示下载对话框。

PS 我最近在研究类似的功能。如果您有问题,请提问。

当您想强制浏览器显示某些文件(或资源)的下载提示时,您必须包含 Content-Disposition:attachment;在响应头中(您已经这样做了)。

我已经通过以下方式分配了 URL - >var file = new Blob([response], { type: 'application/pdf' }); var fileURL = URL.createObjectURL(file)
2021-05-23 22:06:21
我正在使用 Microsoft 报告查看器生成 pdf。没有用于设置下载 url 的实际文件。我已经更新了我的问题以包含响应对象。
2021-06-01 22:06:21
@San,通过下载 url 我的意思是任何网络服务地址(服务器请求),它会返回 pdf 作为响应。因此,如果调用 Microsoft 报告查看器返回 pdf,则需要将相同的调用请求分配给变量 window.location
2021-06-11 22:06:21

一个简单的方法是在您的服务器上使用 GET 方法,并通过查询参数接收您的数据。

然后在您的客户端应用程序中,您只需创建一个经典链接:

<a href="http://your-server.com/your-resource?param1=123&param2=456">Test Link</a>

或者,如果您想从脚本逻辑中管理它,请使用那个简单的 js 脚本:

window.open("http://your-server.com/your-resource?param1=123&param2=456");

在我们的应用程序(angular)中,我们必须为它创建一个对象 url,代码如下:

网络接口:

result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new ByteArrayContent(data);
result.Content.Headers.Add("Content-Type", "application/pdf");
result.Content.Headers.ContentDisposition =
                        new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                        {
                            FileName = "FileNameHere"
                        };

return result;

javascript:

// HttpCall in here
// On SuccessResponse
    var file = new Blob([data], {
                    type: 'application/pdf'
                    });
    var fileURL = URL.createObjectURL(file);
// create an anchor and click on it.
    var ancorTag = document.createElement('a');
    ancorTag.href = fileURL;ancorTag.target = '_blank';
    ancorTag.download = 'CouponOrder.pdf';
    document.body.appendChild(ancorTag);
    ancorTag.click();
    document.body.removeChild(ancorTag);
没有例外。我已经验证了 MyBusinessObject.GenerateMyReport 返回的数据大小,并直接将其写入 pdf 文件。
2021-06-03 22:06:21
这将下载文件。但是在尝试打开时显示为损坏的文件。
2021-06-11 22:06:21
@San,在记事本中打开生成的文件,看看您是否获得了不是 pdf 文档的内容..即 500 错误或您调用的一些异常消息 MyBusinessObject.GenerateMyReport
2021-06-20 22:06:21

创建内容处置并将其添加到您的响应标头

var cd = new System.Net.Mime.ContentDisposition
{
    // for example foo.bak
    FileName = System.IO.Path.GetFileName(fileName),
    // always prompt the user for downloading, set to true if you want 
    // the browser to try to show the file inline
    Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());

您的问题是 GetMyDocument 函数将接收 PDF 文件作为服务器响应,而目前您没有对该响应执行任何操作。您需要在 then 回调中处理响应。从 javascript 保存文件并不简单,因此我建议使用外部库(例如filesaver.js)来帮助您。

它最终会看起来像......

_getMyDocument(e) {
    GetMyDocument(this.props.mydata)
    .then((response)=> {
        const returnedFile = new Blob([response], { type: 'application/pdf'});
        saveAs(returnedFile);
    }).catch(error=> {

    });
它也下载。但它不是空白页,而是在打开文件时出现无效的 pdf 数据错误。
2021-05-31 22:06:21
仔细研究了一下,我认为我们需要使用 blob 而不是文件 - 我已经编辑过。
2021-06-15 22:06:21
尝试使用 Filesaver.js 如何从响应中读取数据?。new File() 需要两个参数并需要数据为数组。
2021-06-20 22:06:21
如果你使用 new Blob([response.data]) 呢?
2021-06-20 22:06:21
var file = new Blob([response], { type: 'application/pdf' }); FileSaver.saveAs(文件); 这将生成空白文档。这在传递给 Blob 之前需要任何转换吗?
2021-06-21 22:06:21