1

I have a Javascript app. When I click on a button, a JSON object is sent using POST request to a Django-Pisa remote server to create a PDF file from the JSON object. I have to use POST since the JSON length is way over the GET allowable length.

This is my Django render function

@csrf_exempt
def render_to_pdf(request):
  request_data = ast.literal_eval(request.POST.keys()[0])
  template_src = templates_map.TEMPLATES_MAP[request_data['intervention']]
  context_json = request_data['data']
  template = get_template(template_src)
  context = Context(context_json)
  html  = template.render(context)
  result = StringIO.StringIO()

  pdf = pisa.pisaDocument(StringIO.StringIO(html), result,link_callback=fetch_resources)

  if not pdf.err:
    return HttpResponse(result.getvalue(), content_type='application/pdf')
  return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))

On the javascript side, this is the click event

try {
  jQuery.post('http://pdfgen-server/pdfgen', JSON.stringify(requestData), 
    function(data) {
      var w = window.open();
      w.document.write(data);
    });
}
catch (err) {
  ; //error handling
}

When I click what I get back is a new window and the content, instead a PDF file rendered, is literally the PDF content (something as if I open notepad to view a PDF file). First few lines in the new browser window:

%PDF-1.4 % ReportLab Generated PDF document http://www.reportlab.com % 'BasicFonts': class PDFDictionary 1 0 obj % The standard fonts dictionary << /F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R >> endobj % 'F1': class PDFType1Font 2 0 obj % Font Helvetica << /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> endobj % 'F2': class PDFType1Font 3 0 obj % Font Times-Roman << /BaseFont /Times-

Please let me know how I can solve this problem?

Thanks

Nghi Vo
  • 155
  • 2
  • 12

1 Answers1

1

I'm not actually sure this will work, but give this a try -

try {
  jQuery.post('http://pdfgen-server/pdfgen', JSON.stringify(requestData), 
    function(data) {
      window.open("data:application/pdf," + escape(data));
    });
}
catch (err) {
  ; //error handling
}

(If it does work, then credit to this question)

Community
  • 1
  • 1
Aidan Ewen
  • 13,049
  • 8
  • 63
  • 88
  • Actually, it should be window.open("data:application/pdf," + escape(data)); – Nghi Vo Mar 08 '13 at 22:34
  • The trick does not work in IE6/7, works fine in Chrome. IE 6/7 does not support dataURI. Unfortunately, I got stuck with IE. – Nghi Vo Mar 08 '13 at 22:37
  • I'll update my answer to use the escape function. Not sure how to handle ie6/7. I think what you really want to do is submit the Json post data as if it were a form, but I'm not sure how you'd do that. Perhaps you can create a form on the fly, but swap the form form data for your json before the form actually submits. – Aidan Ewen Mar 08 '13 at 22:45
  • There's not much that can be done for this solution in any version of IE -- they put a pretty low limit on how long the URL can be: 2048 characters. – Jeff Sep 19 '14 at 19:28