Prompt file download

爷,独闯天下 提交于 2019-11-27 07:35:36

问题


I have a link on my page on click of which I am trying to generate a PDF document and then show the "Open - Save" prompt on the browser.

My HTML (reactjs component) has the below code where onclick calls the _getMyDocument function which then calls a Webapi method.

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

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

  });

My Controller has the below code

[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;
  }

Currently all the code executes but I don't get the file PDF download prompt. What am I doing wrong here?

Response object on success from the ajax call lokks like below


回答1:


Your response from the server looks good. The missing part is that you are not handling this response from the client side in the correct way.

Lets assume that your resource url object looks like below in js. (i.e. you already know the resource url, if you don't know it yet, then you will need a separate call to the server to know the download url)

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

All you need to do is set,

window.location = item.downloadUrl;

This will cause the browser to request a resource from the server, the response from the server must include Content-Disposition:attachment;. It will cause the browser to show the download dialog.

P.S. I have recently worked on a similar functionality. If you have questions please ask.

When you want to force the browser to show the download prompt for some files (or resources), you must include Content-Disposition:attachment; in the response header (which you already did).




回答2:


A simple way to do this is on your server to use GET method, and receive your data by query parameters.

Then in your client app you just have to create a classic link:

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

Or use that simple js script if your want to manage it from your script logic:

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



回答3:


Your issue is that the GetMyDocument function will receive the PDF file as a server response, and currently you are doing nothing with that response. You need to handle the response in the then callback. Saving files from javascript is not entirely simple, so I would recommend using an external library such as filesaver.js to help you.

It will end up looking something like...

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

    });



回答4:


In our app(angular) we had to create an object url for that with a code like:

WebApi:

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);



回答5:


Create Content Disposition and add it to your response header

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());


来源:https://stackoverflow.com/questions/40662885/prompt-file-download

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!