Como baixar o arquivo do httpServlet com Jquery?

Na minha aplicação, um object json é criado no lado do cliente. Este object é postado em um HttpServlet que cria um arquivo pdf baseado nos dados POST.

O arquivo é enviado de volta ao usuário. A function succes é chamada e os dados do stream são registrados. Eu quero, no entanto, que o arquivo seja baixado.

Como conseguir isso?

Meu código do cliente:

$(document).ready(function() { // when the print button is clicked $('#exportButton').click(function() { var tableIdx = performanceDetailTableController.getTableIdx(); var allData = { "shipTable1":{ "rows":[ { "latitude":"12323","longitude":"213213"}, { "latitude":"213213","longitude":"543543"} ]}, "shipTable2":{ "rows":[ { "latitude":"12323", "longitude":"213213"}, { "latitude":"213213","longitude":"543543"} ]} } var postData = JSON.stringify(allData); $.ajax({ type : "POST", url : 'pdfServlet', contentType: "application/json; charset=utf-8", data : postData, async : false, success : function(data) { alert("got some data"); console.log(data); }, }); }); 

});

E o servlet criando o arquivo:

 @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // get the json content StringBuffer jsonContent = getPostedContent(request); log.info(jsonContent.toString()); // convert json to pojo's Tables tables = getTablesFromString(jsonContent); // create a xml stream ByteArrayOutputStream xml = new XmlConverter().getXMLSource(tables); // put the xml on the request request = setXmlOnRequest(request, xml); // create pdf data of the pdf-able xml content ByteArrayOutputStream pdf = new PdfHandler().createPdfDataStream(request); // response = createResponseheaders(response, request); response.setContentType("application/pdf"); response.setContentLength(pdf.size()); response.setHeader("Content-disposition", "attachment; filename=test.pdf"); response.setCharacterEncoding("utf-8"); response.getOutputStream().write(pdf.toByteArray()); //close the streams pdf.close(); response.getOutputStream().close(); } 

A saída no log:

 %PDF-1.4 % 4 0 obj <> endobj 5 0 obj <> stream xwTSϽ7PhRHH.*1 J 

* MINHA SOLUÇÃO: *

veja http://www.particletree.com/notebook/ajax-file-download-or-not/ para um ponteiro

Eu criei um formulário com um campo oculto:

      

do que eu mudei o meu controlador de dados pós-jquery para:

  $('#exportButton').click(function() { var tableIdx = performanceDetailTableController.getTableIdx(); var allData = { "shipTable1":{ "rows":[ { "latitude":"12323","longitude":"213213"}, { "latitude":"213213","longitude":"543543"} ]}, "shipTable2":{ "rows":[ { "latitude":"12323", "longitude":"213213"}, { "latitude":"213213","longitude":"543543"} ]} } var postData = JSON.stringify(allData); // put the data on the hidden form field in the export form $('#pdf_data').val(postData); // and submit the form $('#exportForm').submit(); }); 

agora, quando clico no botão de exportação, o campo oculto no formulário obtém os dados para postar e os dados são postados como www-form codificados.

Dessa forma, o servlet pode manipular a solicitação e o arquivo é baixado para o cliente.

Você não pode baixar arquivos com ajax. O JavaScript tem por razões óbvias de segurança nenhum recurso para acionar um diálogo Salvar como com conteúdo gerado / recuperado arbitrariamente no contexto JavaScript. A world wide web teria parecido muito diferente se isso fosse possível.

Se você insistir em usar JS / jQuery para isso, precisará enviar uma solicitação GET synchronus. Você pode fazer isso com window.location (você só precisa renomear doPost() para doGet() ).

 window.location = 'pdfServlet?param1=value1&param2=value2'; 

Alternativamente, apenas jogue fora todo o JS / jQuery desnecessário e apenas use o HTML simples

com . Bônus adicional é que ele funciona em navegadores com o JS desativado.

Se a sua única razão para pegar o ajax é na verdade uma tentativa ingênua de evitar que a página seja atualizada, posso dizer que isso realmente não acontecerá se a resposta tiver um header Content-Disposition: attachment . Então essa parte já está segura.