Search code examples
javascriptajaxcherrypy

Download a file using cherrypy


I have a cherrypy server, which i'm using to generate REST API requests from the client.

One of the methods from the API doesn't return a JSON as the other, but a CSV file.

/myMethod/report/?name=a&fromRow=1&toRow=1000

I want download this file from the client by clicking a button. However, it's must be passed trough the cherrypy, and not directly from the client.

Here is my ajax function:

  function myReport(name){
  $.ajax(  {
            url : '/myMethod/myReport?name='+name,
            type: 'POST',
            dataType: "text",
            success:function(data, textStatus, jqXHR) {
                window.open(data, "Statistics Report", "width=800, height=200", true);
            },
            error: function(jqXHR, textStatus, errorThrown)
            {
                alert('error')
            }
    });

  }

And here is my cherrypy function:

@cherrypy.expose
def myReport(self, name):
    url = "myReport/?name=" + name + "&fromRow=1&toRow=1000"
    htmlText = self.general_url(url)
    cherrypy.response.headers['Content-Type'] = 'application/json'
    return htmlText

The value htmlText is the URL to the file. I want to pass this value to window.open. However, the actual value that has been passed to window.open is the content of the CSV file, and not the URL link to the file (a new window is opened, with the file content a the URL). I don't want to "solve" the issue by directly download the file from the ajax function, as it must be generated through the cherrypy.

Is anyone know what is the issue?


Solution

  • When you view this content for window.open, you will see first parameter is the url to open in the popup window so your popup window opens your CSV content naturally if you do not set content-type response header in cherrypy side. If you want to show the link of the file, you need to open a popup window with empty url and give your ajax result to popup window, like this in your success function of the ajax call;

    var newWindow=window.open("", "Statistics Report", "width=800, height=200", true);
    newWindow.document.body.innerHTML='<a href="'+data+'">'+data+'</a>';
    

    if you want to show an empty popup and start download then;

    newWindow.location.href=data;
    

    But on the cherrypy side, you need set response content-type like this;

    cherrypy.serving.response.headers["Content-Type"]='application/octet-stream';
    

    Otherwise, cherrypy set it as text/html so your browser tries to show it in popup window