webentwicklung-frage-antwort-db.com.de

Prompt-Dateidownload

Ich habe auf meiner Seite einen Link, auf den ich klicken möchte, um ein PDF -Dokument zu generieren und dann die Aufforderung "Öffnen - Speichern" im Browser anzuzeigen.

In meinem HTML-Code (Reaktjs-Komponente) befindet sich der folgende Code, in dem onclick die _getMyDocument-Funktion aufruft, die dann eine Webapi-Methode aufruft.

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

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

  });

Mein Controller hat den folgenden 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;
  }

Derzeit wird der gesamte Code ausgeführt, aber ich bekomme nicht die Eingabeaufforderung zum Herunterladen der Datei PDF. Was mache ich hier falsch?

Antwortobjekt bei Erfolg von den Ajax Call-Lokks wie unten

 enter image description here

16
San

Ihre Antwort vom Server sieht gut aus. Der fehlende Teil ist, dass Sie diese Antwort auf der Clientseite nicht korrekt behandeln.

Nehmen wir an, dass Ihr Ressourcen-URL-Objekt in js wie folgt aussieht. (Das heißt, Sie kennen bereits die Ressourcen-URL, wenn Sie sie noch nicht kennen, benötigen Sie einen separaten Aufruf an den Server, um die Download-URL zu kennen.)

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

Alles was Sie tun müssen, ist 

window.location = item.downloadUrl;

Dies veranlasst den Browser, eine Ressource vom Server anzufordern, die Antwort vom Server muss include Content-Disposition:attachment;. Der Browser zeigt dann den Download-Dialog an.

P.S. Ich habe kürzlich an einer ähnlichen Funktionalität gearbeitet. Bei Fragen bitte anfragen.

Wenn Sie möchten, dass der Browser die Download-Eingabeaufforderung für einige Dateien (oder Ressourcen) anzeigt, müssen Sie Content-Disposition:attachment; in den Antwortheader einfügen (was Sie bereits getan haben).

7
ScrapCode

Eine einfache Möglichkeit, dies zu tun, besteht auf Ihrem Server, um die GET-Methode zu verwenden und Ihre Daten über Abfrageparameter zu empfangen.

Dann müssen Sie in Ihrer Client-App nur einen klassischen Link erstellen:

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

Oder verwenden Sie dieses einfache js-Skript, wenn Sie es von Ihrer Skriptlogik aus verwalten möchten:

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

Ihr Problem ist, dass die GetMyDocument-Funktion die PDF -Datei als Serverantwort erhält und Sie derzeit nichts mit dieser Antwort tun. Sie müssen die Antwort im Callback behandeln. Das Speichern von Dateien aus Javascript ist nicht ganz einfach. Daher würde ich empfehlen, eine externe Bibliothek wie filesaver.js zu verwenden, um Ihnen zu helfen.

Es wird am Ende so aussehen wie ...

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

    });
0
Alex Young

In unserer App (eckig) mussten wir eine Objekt-URL mit einem Code wie dem folgenden erstellen:

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);
0
Ermir Beqiraj

Erstellen Sie die Inhaltsdisposition und fügen Sie sie Ihrem Antwortheader hinzu 

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