Pregunta Descargue y abra el archivo pdf usando Ajax


Tengo una clase de acción que genera un pdf. los contentType está configurado apropiadamente.

public class MyAction extends ActionSupport 
{
   public String execute() {
    ...
    ...
    File report = signedPdfExporter.generateReport(xyzData, props);

    inputStream = new FileInputStream(report);
    contentDisposition = "attachment=\"" + report.getName() + "\"";
    contentType = "application/pdf";
    return SUCCESS;
   }
}

Yo llamo esto action  a través de una llamada Ajax. No sé cómo entregar esta transmisión al navegador. Intenté algunas cosas pero nada funcionó.

$.ajax({
    type: "POST",
    url: url,
    data: wireIdList,
    cache: false,
    success: function(response)
    {
        alert('got response');
        window.open(response);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) 
    {
        alert('Error occurred while opening fax template' 
              + getAjaxErrorString(textStatus, errorThrown));
    }
});

Lo anterior da el error:

Su navegador envió una solicitud que este servidor no pudo entender.


74
2018-01-04 13:42


origen


Respuestas:


No necesariamente necesitas Ajax para esto. Solo una <a> enlace es suficiente si configura el content-disposition a attachment en el código del lado del servidor. De esta manera, la página principal se mantendrá abierta, si esa era su principal preocupación (¿por qué habría elegido innecesariamente Ajax para esto?). Además, no hay forma de manejar esto de manera muy sincronizada. PDF no es datos de caracteres. Son datos binarios. No puedes hacer cosas como $(element).load(). Quieres usar completamente nuevo solicitud de esto Para eso <a href="pdfservlet/filename.pdf">pdf</a> es perfectamente adecuado.

Para ayudarlo más con el código del lado del servidor, deberá contar más sobre el idioma utilizado y publicar un fragmento de los intentos de código.


32
2018-01-04 13:45



Aquí es cómo lo hice funcionar

$.ajax({
  url: '<URL_TO_FILE>',
  success: function(data) {
    var blob=new Blob([data]);
    var link=document.createElement('a');
    link.href=window.URL.createObjectURL(blob);
    link.download="<FILENAME_TO_SAVE_WITH_EXTENSION>";
    link.click();
  }
});

Respuesta actualizada utilizando download.js

$.ajax({
  url: '<URL_TO_FILE>',
  success: download.bind(true, "<FILENAME_TO_SAVE_WITH_EXTENSION>", "<FILE_MIME_TYPE>")
});


104
2017-12-19 10:22



Realmente no creo que ninguna de las respuestas anteriores haya detectado el problema del cartel original. Todos suponen una solicitud GET mientras el póster intentaba PUBLICAR datos y obtener una descarga en respuesta.

En el curso de la búsqueda de una mejor respuesta, encontramos esto Plugin de jQuery para solicitar descargas de archivos tipo Ajax.

En su "corazón" crea un formulario HTML "temporal" que contiene los datos dados como campos de entrada. Este formulario se adjunta al documento y se publica en la URL deseada. Inmediatamente después, el formulario se elimina nuevamente:

jQuery('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
    .appendTo('body').submit().remove()

Actualizar La respuesta de Mayur parece bastante prometedora y muy simple en comparación con el complemento jQuery al que me refería.


29
2018-02-24 14:01



Así es como resuelvo este problema.
La respuesta de Jonathan Amend en esta publicación me ayudo mucho.
El ejemplo a continuación está simplificado.

Para más detalles, el código fuente anterior es capaz de descargue un archivo usando una solicitud JQuery Ajax (GET, POST, PUT, etc.). También ayuda a cargar parámetros como JSON y para cambiar el tipo de contenido a la aplicación / json (mi predeterminado).

los html fuente:

<form method="POST">
    <input type="text" name="startDate"/>
    <input type="text" name="endDate"/>
    <input type="text" name="startDate"/>
    <select name="reportTimeDetail">
        <option value="1">1</option>
    </select>
    <button type="submit"> Submit</button>
</form>  

Una forma simple con dos entradas de texto, una de selección y un elemento de botón.

los página de javascript fuente:

<script type="text/javascript" src="JQuery 1.11.0 link"></script>
<script type="text/javascript">
    // File Download on form submition.
    $(document).on("ready", function(){
        $("form button").on("click", function (event) {
            event.stopPropagation(); // Do not propagate the event.

            // Create an object that will manage to download the file.
            new AjaxDownloadFile({
                url: "url that returns a file",
                data: JSON.stringify($("form").serializeObject())
            });

            return false; // Do not submit the form.
        });
    });
</script>  

Un evento simple al hacer clic en el botón. Crea un objeto AjaxDownloadFile. La fuente de la clase AjaxDownloadFile está debajo.

los Clase AjaxDownloadFile fuente:

var AjaxDownloadFile = function (configurationSettings) {
    // Standard settings.
    this.settings = {
        // JQuery AJAX default attributes.
        url: "",
        type: "POST",
        headers: {
            "Content-Type": "application/json; charset=UTF-8"
        },
        data: {},
        // Custom events.
        onSuccessStart: function (response, status, xhr, self) {
        },
        onSuccessFinish: function (response, status, xhr, self, filename) {
        },
        onErrorOccured: function (response, status, xhr, self) {
        }
    };
    this.download = function () {
        var self = this;
        $.ajax({
            type: this.settings.type,
            url: this.settings.url,
            headers: this.settings.headers,
            data: this.settings.data,
            success: function (response, status, xhr) {
                // Start custom event.
                self.settings.onSuccessStart(response, status, xhr, self);

                // Check if a filename is existing on the response headers.
                var filename = "";
                var disposition = xhr.getResponseHeader("Content-Disposition");
                if (disposition && disposition.indexOf("attachment") !== -1) {
                    var filenameRegex = /filename[^;=\n]*=(([""]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1])
                        filename = matches[1].replace(/[""]/g, "");
                }

                var type = xhr.getResponseHeader("Content-Type");
                var blob = new Blob([response], {type: type});

                if (typeof window.navigator.msSaveBlob !== "undefined") {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    var URL = window.URL || window.webkitURL;
                    var downloadUrl = URL.createObjectURL(blob);

                    if (filename) {
                        // Use HTML5 a[download] attribute to specify filename.
                        var a = document.createElement("a");
                        // Safari doesn"t support this yet.
                        if (typeof a.download === "undefined") {
                            window.location = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location = downloadUrl;
                    }

                    setTimeout(function () {
                        URL.revokeObjectURL(downloadUrl);
                    }, 100); // Cleanup
                }

                // Final custom event.
                self.settings.onSuccessFinish(response, status, xhr, self, filename);
            },
            error: function (response, status, xhr) {
                // Custom event to handle the error.
                self.settings.onErrorOccured(response, status, xhr, self);
            }
        });
    };
    // Constructor.
    {
        // Merge settings.
        $.extend(this.settings, configurationSettings);
        // Make the request.
        this.download();
    }
};

Creé esta clase para agregar a mi biblioteca JS. Es reutilizable Espero que ayude.


6
2018-01-17 17:32



Puedes usar este plugin

jQuery.download = function(url, data, method) {
    //url and data options required
    if (url && data) {
        //data can be string of parameters or array/object
        data = typeof data == 'string' ? data : jQuery.param(data);
        //split params into form inputs
        var inputs = '';
        jQuery.each(data.split('&'), function() {
            var pair = this.split('=');
            inputs += '<input type="hidden" name="' + pair[0] +
                '" value="' + pair[1] + '" />';
        });
        //send request
        jQuery('<form action="' + url +
                '" method="' + (method || 'post') + '">' + inputs + '</form>')
            .appendTo('body').submit().remove();
    };
};


$.download(
    '/export.php',
    'filename=mySpreadsheet&format=xls&content=' + spreadsheetData
);

Esto funcionó para mí. Encontrado este plugin aquí


5
2017-07-17 09:57



Lo que funcionó para mí es el siguiente código, ya que la función del servidor está recuperando File(memoryStream.GetBuffer(), "application/pdf", "fileName.pdf");:

$http.get( fullUrl, { responseType: 'arraybuffer' })
            .success(function (response) {
                var blob = new Blob([response], { type: 'application/pdf' });

                if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                    window.navigator.msSaveOrOpenBlob(blob); // for IE
                }
                else {
                    var fileURL = URL.createObjectURL(blob);
                    var newWin = window.open(fileURL);
                    newWin.focus();
                    newWin.reload();
                }
});

4
2017-07-17 15:24



crea un iframe escondido, luego en tu código ajax arriba:

url:  document.getElementById('myiframeid').src = your_server_side_url,

y eliminar el window.open(response);


2
2017-09-14 12:57