2017-01-24 5 views
1

Я пытаюсь разрешить пользователю загружать файл размером 15 МБ в мою сеть, оттуда этот файл должен быть отправлен на мой веб-сервис, получить ответ (pdf-файл) и подавать его пользователю, чтобы он мог его загрузить.Позвольте пользователю загрузить сгенерированный PDF-файл после загрузки файла

Однако, я заканчивающийся в URL, как это без подсказки, чтобы загрузить что-нибудь, только 404 ошибка: http://localhost:10080/Download?file=%PDF-1.4%%EF%BF%BD%EF%B (etc)

Некоторые пункты:

  • Сначала я сжать файл
  • из предыдущего пункта, я использую Ajax для отправить файл

Ajax код

$("#file").on("change", function(evt) { 

     var files = evt.target.files; 

     /* Create zip file representation */ 
     var zip = new JSZip(); 
     /* Name, content */ 
     zip.file("data.zip", files[0]); 

     zip.generateAsync({ 
      compression: 'DEFLATE', 
      type: 'blob' 
     }).then(function(zc) { // Function called when the generation is complete 
      /* Create file object to upload */ 
      var fileObj = new File([zc], "compressed-data"); 

      /* form data oject */ 
      var formData = new FormData(); 
      /* $('#file')[0].files[0] */ 
      formData.append('attachments', fileObj); 

      $.ajax({ 
       type: "POST", 
       url: $("form#data").attr("action"), 
       data: formData, 
       contentType: false, 
       processData: false, 
       success: function (returnValue, textStatus, jqXHR) { 
        window.location = '/Download?file=' + returnValue; 
       } 
      }) 

Python Web Code

def post(self): 
    attachments = self.request.POST.getall('attachments') 
    #handle the attachment 
    _attachments = [{'content': f.file.read(), 
        'filename': f.filename} for f in attachments] 

    # Use the App Engine Requests adapter. This makes sure that Requests uses 
    # URLFetch. 
    requests_toolbelt.adapters.appengine.monkeypatch() 

    #web service url 
    url = 'http://localhost:8080' 

    files = {'attachments': _attachments[0]["content"]} 

    resp = requests.post(url, files=files) 

    self.response.headers[b'Content-Type'] = b'application/pdf; charset=utf-8' 
    self.response.headers[b'Content-Disposition'] = b'attachment; filename=report.pdf' 
    self.response.out.write(resp.content) 

Python Web Service Code

@app.route('/', methods=['POST']) 
def hello(): 

    #the attached ZIPPED raw data 
    f = request.files["attachments"] 
    #to unzip it 
    input_zip = ZipFile(f) 
    #unzip 
    data = [input_zip.read(name) for name in input_zip.namelist()] 

    generator = pdfGenerator(io.BytesIO(data[0])) 
    return generator.analyzeDocument() 

Генератор PDF использует ReportLab, пишет PDF по io.BytesIO() и возвращает его output = self.buff.getvalue()

1.- Что я делаю неправильно с товаром window location?

2.- Я что-то делаю с типом файла?

Мне уже два дня, теперь мне нужна помощь.

Спасибо.

ответ

1

However, I'm ending in a URL like this with no prompt to download anything, just a 404 error: http://localhost:10080/Download?file=%PDF-1.4%%EF%BF%BD%EF%B (etc)

Вот что вы просите в window.location = '/Download?file=' + returnValue;, перенаправлять пользователя /Download.

Когда вы позвоните в свою службу, вы должны запросить ответ Blob. Затем используйте saveAs (or FileSaver.js, a polyfill) для запуска загрузки.

Насколько я знаю, $.ajax не позволяет загружать двоичный контент из коробки (он попытается декодировать ваш двоичный файл из UTF-8 и испортить его). Либо используйте плагин jQuery (например, jquery.binarytransport.js), либо напрямую используйте xhr.

$.ajax({ 
    type: "POST", 
    url: $("form#data").attr("action"), 
    data: formData, 
    contentType: false, 
    processData: false, 
    dataType: 'binary',      // using jquery.binarytransport.js 
    success: function (returnValue, textStatus, jqXHR) { 
     // Default response type is blob 
     saveAs(returnValue, "result.pdf"); // using FileSaver.js 
    } 
}) 
+0

MASTER! Когда я прочитал это, некоторые вещи не укладывались в мой разум и были немного скептичны. Но после попытки, работает как шарм! Большое спасибо. Однако я не совсем понимаю, почему мне пришлось использовать обе библиотеки, чтобы заставить его работать. – mclzc

+0

После того, как вы «ПОЧТАЙТЕ» zip-файл на ваш сервер, вы хотите сделать 2 вещи: 1/получить двоичный ответ и загрузить 2/триггер. 1/нужен либо плагин jQuery ('$ .ajax' повреждает двоичный контент сам по себе), либо необработанное' XMLHttpRequest' с 'responseType =" blob "' (вы уже используете jQuery, поэтому я использовал первое решение). Для 2/нет (пока) API для выполнения, реализованного в каждом браузере. 'FileSaver.js' обертывает разные способы сделать это в' saveAs'. –

Смежные вопросы