How to download a file when a django function is called by javascript instead of navigation to the url?











up vote
0
down vote

favorite












I have a page where several buttons process different functions like sending a sms (via API), sends a file by email, or downloads a PDF file. Button actions dont use forms, but uses ajax requests via javascript.



I used to create a pdf file using javascript (jspdf), but have written code which generates a pdf file by python on the server. Now I need to allow download when the button is clicked.



Server code snippet:



with NamedTemporaryFile(mode='w+b') as temp:
from django.http import FileResponse
doc = SimpleDocTemplate(temp.name, pagesize=A4, rightMargin=20, leftMargin=20, topMargin=20, bottomMargin=20, allowSplitting=1, title="Prescription", author="MyOPIP.com")
doc.build(elements)
print(f'Generated {temp.name}')
return FileResponse(open(temp.name, 'rb'), content_type='application/pdf')


The above code is supposed to download a pdf file, if called by navigating to the url.



On my javascript side, I tried to determine what I'm receiving:



$.ajax({
url: `/clinic/${cliniclabel}/prescription/download/patient/${patient_id}`,
dataType: "html",
data: data,
type: 'POST',
success: function (data) {
console.log("Received data from server..type is ", typeof(data))
console.log(data)
}
});


And I get:



Received data from server..type is  string
%PDF-1.4
%���� ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<<
/F1 2 0 R /F2 5 0 R
>>
endobj
2 0 obj....


Apparently django sends this as a file stream. How can I get the file downloaded to the user when the response is processed by javascript?










share|improve this question




























    up vote
    0
    down vote

    favorite












    I have a page where several buttons process different functions like sending a sms (via API), sends a file by email, or downloads a PDF file. Button actions dont use forms, but uses ajax requests via javascript.



    I used to create a pdf file using javascript (jspdf), but have written code which generates a pdf file by python on the server. Now I need to allow download when the button is clicked.



    Server code snippet:



    with NamedTemporaryFile(mode='w+b') as temp:
    from django.http import FileResponse
    doc = SimpleDocTemplate(temp.name, pagesize=A4, rightMargin=20, leftMargin=20, topMargin=20, bottomMargin=20, allowSplitting=1, title="Prescription", author="MyOPIP.com")
    doc.build(elements)
    print(f'Generated {temp.name}')
    return FileResponse(open(temp.name, 'rb'), content_type='application/pdf')


    The above code is supposed to download a pdf file, if called by navigating to the url.



    On my javascript side, I tried to determine what I'm receiving:



    $.ajax({
    url: `/clinic/${cliniclabel}/prescription/download/patient/${patient_id}`,
    dataType: "html",
    data: data,
    type: 'POST',
    success: function (data) {
    console.log("Received data from server..type is ", typeof(data))
    console.log(data)
    }
    });


    And I get:



    Received data from server..type is  string
    %PDF-1.4
    %���� ReportLab Generated PDF document http://www.reportlab.com
    1 0 obj
    <<
    /F1 2 0 R /F2 5 0 R
    >>
    endobj
    2 0 obj....


    Apparently django sends this as a file stream. How can I get the file downloaded to the user when the response is processed by javascript?










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have a page where several buttons process different functions like sending a sms (via API), sends a file by email, or downloads a PDF file. Button actions dont use forms, but uses ajax requests via javascript.



      I used to create a pdf file using javascript (jspdf), but have written code which generates a pdf file by python on the server. Now I need to allow download when the button is clicked.



      Server code snippet:



      with NamedTemporaryFile(mode='w+b') as temp:
      from django.http import FileResponse
      doc = SimpleDocTemplate(temp.name, pagesize=A4, rightMargin=20, leftMargin=20, topMargin=20, bottomMargin=20, allowSplitting=1, title="Prescription", author="MyOPIP.com")
      doc.build(elements)
      print(f'Generated {temp.name}')
      return FileResponse(open(temp.name, 'rb'), content_type='application/pdf')


      The above code is supposed to download a pdf file, if called by navigating to the url.



      On my javascript side, I tried to determine what I'm receiving:



      $.ajax({
      url: `/clinic/${cliniclabel}/prescription/download/patient/${patient_id}`,
      dataType: "html",
      data: data,
      type: 'POST',
      success: function (data) {
      console.log("Received data from server..type is ", typeof(data))
      console.log(data)
      }
      });


      And I get:



      Received data from server..type is  string
      %PDF-1.4
      %���� ReportLab Generated PDF document http://www.reportlab.com
      1 0 obj
      <<
      /F1 2 0 R /F2 5 0 R
      >>
      endobj
      2 0 obj....


      Apparently django sends this as a file stream. How can I get the file downloaded to the user when the response is processed by javascript?










      share|improve this question















      I have a page where several buttons process different functions like sending a sms (via API), sends a file by email, or downloads a PDF file. Button actions dont use forms, but uses ajax requests via javascript.



      I used to create a pdf file using javascript (jspdf), but have written code which generates a pdf file by python on the server. Now I need to allow download when the button is clicked.



      Server code snippet:



      with NamedTemporaryFile(mode='w+b') as temp:
      from django.http import FileResponse
      doc = SimpleDocTemplate(temp.name, pagesize=A4, rightMargin=20, leftMargin=20, topMargin=20, bottomMargin=20, allowSplitting=1, title="Prescription", author="MyOPIP.com")
      doc.build(elements)
      print(f'Generated {temp.name}')
      return FileResponse(open(temp.name, 'rb'), content_type='application/pdf')


      The above code is supposed to download a pdf file, if called by navigating to the url.



      On my javascript side, I tried to determine what I'm receiving:



      $.ajax({
      url: `/clinic/${cliniclabel}/prescription/download/patient/${patient_id}`,
      dataType: "html",
      data: data,
      type: 'POST',
      success: function (data) {
      console.log("Received data from server..type is ", typeof(data))
      console.log(data)
      }
      });


      And I get:



      Received data from server..type is  string
      %PDF-1.4
      %���� ReportLab Generated PDF document http://www.reportlab.com
      1 0 obj
      <<
      /F1 2 0 R /F2 5 0 R
      >>
      endobj
      2 0 obj....


      Apparently django sends this as a file stream. How can I get the file downloaded to the user when the response is processed by javascript?







      javascript python ajax django






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 days ago

























      asked 2 days ago









      Joel G Mathew

      1,83492643




      1,83492643
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          It is impossible to do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns).



          That being said, the work around would be to set the "src" of an anchor tag to the url for the file download and trigger a click on it.



          Note: You'll have to change your function method from POST to GET




          • Change the "button" to an "a" link and have src="#" in the html.

          • Add an ng-click to it to trigger a JS function

          • In the JS function, do not call event.PreventDefault(); and then update the "src" of the "a" tag.

          • Once function is done executing, then it'll trigger the normal click on the <a> tag anyway (with the source updated)


          I haven't tested the above; so if that doesn't work, move the try the following:




          • Keep the button as is

          • Add a new hidden <a> tag with src="#"

          • In the JS function, update the src of the <a> tag and trigger click on the element.


          Comment under here if you have any questions.






          share|improve this answer





















          • Why not just add a window.open javascript method, and navigate to the new url?
            – Joel G Mathew
            yesterday











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53348420%2fhow-to-download-a-file-when-a-django-function-is-called-by-javascript-instead-of%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          It is impossible to do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns).



          That being said, the work around would be to set the "src" of an anchor tag to the url for the file download and trigger a click on it.



          Note: You'll have to change your function method from POST to GET




          • Change the "button" to an "a" link and have src="#" in the html.

          • Add an ng-click to it to trigger a JS function

          • In the JS function, do not call event.PreventDefault(); and then update the "src" of the "a" tag.

          • Once function is done executing, then it'll trigger the normal click on the <a> tag anyway (with the source updated)


          I haven't tested the above; so if that doesn't work, move the try the following:




          • Keep the button as is

          • Add a new hidden <a> tag with src="#"

          • In the JS function, update the src of the <a> tag and trigger click on the element.


          Comment under here if you have any questions.






          share|improve this answer





















          • Why not just add a window.open javascript method, and navigate to the new url?
            – Joel G Mathew
            yesterday















          up vote
          0
          down vote













          It is impossible to do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns).



          That being said, the work around would be to set the "src" of an anchor tag to the url for the file download and trigger a click on it.



          Note: You'll have to change your function method from POST to GET




          • Change the "button" to an "a" link and have src="#" in the html.

          • Add an ng-click to it to trigger a JS function

          • In the JS function, do not call event.PreventDefault(); and then update the "src" of the "a" tag.

          • Once function is done executing, then it'll trigger the normal click on the <a> tag anyway (with the source updated)


          I haven't tested the above; so if that doesn't work, move the try the following:




          • Keep the button as is

          • Add a new hidden <a> tag with src="#"

          • In the JS function, update the src of the <a> tag and trigger click on the element.


          Comment under here if you have any questions.






          share|improve this answer





















          • Why not just add a window.open javascript method, and navigate to the new url?
            – Joel G Mathew
            yesterday













          up vote
          0
          down vote










          up vote
          0
          down vote









          It is impossible to do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns).



          That being said, the work around would be to set the "src" of an anchor tag to the url for the file download and trigger a click on it.



          Note: You'll have to change your function method from POST to GET




          • Change the "button" to an "a" link and have src="#" in the html.

          • Add an ng-click to it to trigger a JS function

          • In the JS function, do not call event.PreventDefault(); and then update the "src" of the "a" tag.

          • Once function is done executing, then it'll trigger the normal click on the <a> tag anyway (with the source updated)


          I haven't tested the above; so if that doesn't work, move the try the following:




          • Keep the button as is

          • Add a new hidden <a> tag with src="#"

          • In the JS function, update the src of the <a> tag and trigger click on the element.


          Comment under here if you have any questions.






          share|improve this answer












          It is impossible to do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns).



          That being said, the work around would be to set the "src" of an anchor tag to the url for the file download and trigger a click on it.



          Note: You'll have to change your function method from POST to GET




          • Change the "button" to an "a" link and have src="#" in the html.

          • Add an ng-click to it to trigger a JS function

          • In the JS function, do not call event.PreventDefault(); and then update the "src" of the "a" tag.

          • Once function is done executing, then it'll trigger the normal click on the <a> tag anyway (with the source updated)


          I haven't tested the above; so if that doesn't work, move the try the following:




          • Keep the button as is

          • Add a new hidden <a> tag with src="#"

          • In the JS function, update the src of the <a> tag and trigger click on the element.


          Comment under here if you have any questions.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered yesterday









          Pranay Majmundar

          1655




          1655












          • Why not just add a window.open javascript method, and navigate to the new url?
            – Joel G Mathew
            yesterday


















          • Why not just add a window.open javascript method, and navigate to the new url?
            – Joel G Mathew
            yesterday
















          Why not just add a window.open javascript method, and navigate to the new url?
          – Joel G Mathew
          yesterday




          Why not just add a window.open javascript method, and navigate to the new url?
          – Joel G Mathew
          yesterday


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53348420%2fhow-to-download-a-file-when-a-django-function-is-called-by-javascript-instead-of%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin