I have an application that generates a PDF on the fly (accessed via service/generatePdf).
It returns a HTTP response with content-type="application/pdf" and the outputStream set to the binary contents.
Per business specs, when the user clicks a button we need to open a new window/tab that displays that PDF.
Submitting the form below, that all works beautifully on the Happy Path, where the response is an actual PDF.
<form action="service/generatePdf" method="post" name="PdfForm" target="_blank">
However, what does not work so well is when the PDF can't be generated for whatever reason. For example, let's say that the HTTP response outputStream is empty.
What I want to be able to do is display a nice error message on the first page, and not open the new window/tab.
But there doesn't seem to be any way to do it. Your choices seem to be
Return a valid PDF, or
Live with how the browser's PDF plugin handles corrupt files
I've tried jQuery, Ajax, the jQuery Form Plugin, the jQuery Download plugin plugin, and nothing seems to work.
The server should indicate error or success through a HTTP status code (e.g. 200 = OK, 500 = error). This you can catch in your REST client, with JQuery
$.ajax({
url: 'service/generatedPDF',
error: function(jqXHR, textStatus, errorThrown) {
... // show error message
},
).done(function(data) {
// data contains the PDF
}
It would be better to just create the PDF on the server, put it in a temporary store and send the URL to this PDF in the response. Once the client downloads the file, or after a certain download, the PDF is removed from the store.
In that case you would just open a new window with the URL you received from the server.
If the server provides the PDF in the initial request, you can convert it to a Data URI and open that data URI in a new window.
This is a fairly common requirement. You need to make your REST app a little smarter. It needs to check the result of the LiveCycle PDF generation and, if it wasn't successful, return an HTML response (with a content-type of text/html).
The browser is fairly dumb. It examines the content-type of the incoming response and, based on the content-type, launches the plug-in. It's then up to the plug-in to process the response. The PDF plug-in is also not so bright, it assumes that the incoming data stream is a PDF and if it's empty, it produces an error.
The key here is to send down the right content-type (and content) to the browser, which means checking the PDF result and sending a more appropriate response if the PDF result is a failure.
We often see this in LiveCycle orchestrations too. The temptation is to generate the PDF into a com.adobe.idp.Document object and then return that object directly. This leads to similar problems that you describe. Instead, the better approach is to check the result of the PDF generation. If it is valid, then return that response. If the PDF generation failed, then construct an HTML response in a com.adobe.idp.Document object (with the appropriate text/html content-type) and then return that instead.
Related
I am working on a nodejs service where I need to read a PDF document from a file.
At a high level, here is the workflow. First time a user requests a PDF, I generate it (using pdfkitjs) and save it to the server. Then, when the user request the same document again, I need to read it from the server and send it back.
Is there a way that I can use PDFDocument from pdfkitjs to read the contents from the file and create a corresponding PDFDocument? Almost all searches come up with how to pipe the PDF to a stream, but now how to read from a stream.
If "the stream" is your server response then you shouldn't have to do much more than add the appropriate headers to the response first.
I'm trying to do client-side processing of some data sent in a server's HTTP response.
Here's what I'm working with: I have a web application that sends commands to a backend simulation engine, which then sends back a bunch of data/results in the response body. I want to be able to access this response using JavaScript (note..not making a new response, but simply accessing the data already sent from the server).
Right now, I am able to do this via a kludgy hack of sorts:
var responseText = "{{response}}";
This is using Django's template system, where I have already pre-formatted the template context variable "response" to contain a pre-formatted string representation of a csv file (i.e., proper unicode separators, etc).
This results in a huge string being transmitted to the page. Right now, this supports my immediate goal of making this data available for download as a csv, but it doesn't really support more sophisticated tasks. Also, I'm not sure if it will scale well when my string is, say, 2 MB as opposed to less than 1 KB.
I'd like to have this response data stored more elegantly, perhaps as part of the DOM or maybe in a cache (?) [not familiar with this].
The ideal way to do this is to not load the csv on document load, either as a javascript variable or as part of the DOM. Why would you want to load a 2MB data every time to the user when his intention may not be to download the csv everytime?
I suggest creating a controller/action for downloading the csv and get it on click of the download button.
I have a link in an email which looks like this:
...DownloadReport?id=1
This first redirects to a login page where the user logs in. On login success, I run this JavaScript to return the actual report:
function getReport() {
$.ajax({ url: "/PropertySearch/Order/GetReport" });
}
The response to this includes the report (it is a tif). However, the browser does not pop up a "Would you like to open or save this document?"
How do I get the browser to recognize that the response is a document and thus prompt to open or save?
You don't necessarily need Ajax for this. Just an link is enough if you set the content-disposition to attachment in the server side code. This way the parent page will just stay open, if that was your major concern (why would you unnecessarily have chosen Ajax for this otherwise?). Besides, there is no way to handle this nicely acynchronously. PDF is not character data. It's binary data. You can't do stuff like $(element).load(). You want to use completely new request for this.For that pdf is perfectly suitable.
In my app I have used canvas on which the user can draw images. On save button I get the dataURL from the canvas. Now I want to save the image created by user on the server(node.js).
I have read Node file system documentation but I am not sure what I can/should use! Also up till now I have only used forms for posting data to server and now I need to post the data on the click of save button, what should I do?
So there are two parts to the answer,
Client behavior and server behavior. There's a lot of raw information missing here.
First we assume you have a mechanism of getting the raw stream for the content in the format it needs to be when you convert it to an image "file" or binary content in a datastore (or xml for svg, etc.) If you have that raw stream content you're going to use a standard XmlHttpRequest to post the content to a url. On the node.js process you need a route and a function that is going to "catch" the streamed content and persist it in your storage mechanism (file, db as blob, export to an external service, etc.)
So when you ask how on the client side, it's by posting to a url using XmlHttpRequest (dojo.xhr, jQuery.ajax, etc.) stream the raw content out as the "body" of the post programatically. Bind a function to a dom element's onClick method that takes the image content and posts it to the server url.
jQuery('#postDiv').click(function() {
jQuery.ajax({
type : 'POST',
url : '/myapp/image/<id>',
data : someComponentInMyPage.getImageContent(),
success : function() { // show the user it worked },
datatype : 'image/png' // or whatever format is coming out
});
});
On the server, take the input stream and write it to a file, this is going to depend on the frameworks/modules you're using on the node side.
We have a HTML page containing the HTML table which is populated dynamically with content from server. The requirement is to able to export the HTML table to excel in IE as well as Firefox.
We are trying following approach -
The HTML table is first being sent to the server with the content as a POST request using XHR.
at the server side there is HttpServlet which is sending the content back with MIME type as "application/vnd.ms-excel" as a repsonse to the POST request.
At the browser the status of request is monitored and is observed as 200. However we are not getting any prompt from browser for opening the excel.
Appreciate if someone can help with this and throw some light on what we are missing on.
Thanks,
Adish
You have to use form submit instead of XHR if you want a single one POST request to handle that.
If you want to use ajax. The excel file needs to be cached or persisted somewhere. The server returns the url for the excel file in response of xhr post. Then in the success callback use window.open(url) to GET the file, which will prompt for downloading. This will use two requests.
I am not sure if iframe can work around.