AJAX: отправить файл сервлету и открыть ответ в новом окне
В моем приложении пользователи могут редактировать файл ODF через WebODF ( http://webodf.org/). При сохранении я хочу отправить отредактированный файл сервлету, сделать так, чтобы он конвертировался в PDF через ODFDOM ( http://code.google.com/p/xdocreport/wiki/ODFDOMConverterPDFViaIText) и открывался в новом окне.
В настоящее время я пытаюсь сделать это через AJAX. Все работает хорошо до того момента, когда я пытаюсь открыть полученный файл PDF.
Мой Javascript:
function showPDF(pServletUrl)
{
var successCallback = function(pData)
{
var mimetype = "application/vnd.oasis.opendocument.text";
var blob = new Blob([pData.buffer], {type: mimetype});
var formData = new FormData();
formData.append("file", blob, "test.odt");
jQuery.ajax({
type: "POST",
url: pServletUrl,
async: false,
data: formData,
processData: false,
contentType: false,
success: function(pSuccessData)
{
window.open(pSuccessData);
},
error: function(pErrorData)
{
console.log(pErrorData);
}
});
}
var errorCallback = function(data)
{
console.log(error);
}
_canvas.odfContainer().createByteArray(successCallback, errorCallback);
}
Мой сервлет:
public void handleRequest(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException
{
BufferedInputStream tBufferedInput = null;
BufferedOutputStream tBufferedOutput = null;
try
{
List<FileItem> tItems = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(pRequest);
for (FileItem tItem : tItems)
{
if (!tItem.isFormField())
{
String tFieldname = tItem.getFieldName();
String tFilename = FilenameUtils.getName(tItem.getName());
InputStream tFilecontent = tItem.getInputStream();
if("file".equals(tFieldname))
{
tBufferedInput = new BufferedInputStream(tFilecontent);
pResponse.reset();
pResponse.setHeader("Content-Type", "application/pdf");
pResponse.setHeader("Content-Disposition", "inline; filename=\"" + "test.pdf" + "\"");
tBufferedOutput = new BufferedOutputStream(pResponse.getOutputStream(), 10240);
this.getOdtAsPdf(tBufferedInput, tBufferedOutput);
tBufferedOutput.flush();
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
tBufferedInput.close();
tBufferedOutput.close();
}
catch(Exception e)
{
}
}
}
private void getOdtAsPdf(InputStream pInputStream, OutputStream pOutputStream) throws Exception
{
OdfDocument tOdfDocument = OdfDocument.loadDocument(pInputStream);
PdfOptions tPdfOptions = PdfOptions.create();
PdfConverter.getInstance().convert(tOdfDocument, pOutputStream, tPdfOptions);
}
Похоже, что Javascript хочет проанализировать полученный PDF-файл как URL-адрес и (очевидно) не может это сделать. Есть ли способ, чтобы просто открыть файл в новом окне, или мне нужно найти другой способ сделать это?
2 ответа
Вы можете использовать встроенный тег для отображения вашего блоба после вызова ajax.
Используйте метод createObjectUrl, чтобы получить URL-адрес из BLOB-объекта, а затем отобразить PDF-файл.
Вы не можете открыть файл с помощью Ajax. Это ограничение безопасности для JavaScript. У вас есть несколько обходных путей:
- используйте плагин, который дает опыт типа Ajax, но открывает файл в новом окне. подробнее здесь
- есть форма, которая представляется в новом окне.
<form target=_blank />
это приведет к открытию нового окна, что не изменит содержимого вашей текущей страницы. - Другой вариант (не такой аккуратный) - сохранить файл в сессии и в ответе вашего AJAX передать идентификатор. Затем с помощью Javascript совершите звонок используя
window.open('downloadurl?id')
который отправит ответ вашего PDF файла.