1

Context

Summarizing, I have an app that sends some file or JSON to a Django server, the server then process the file and create a new zip file. This zip file have to return to the app. I'm trying to do this with a POST request only, returning the file as a response. I was able to download the file as a response with Postman and I can also see the response I want inside one of the HttpErrorResponse attributes. I also found an answer that was able to do the same, but in Java.

Some informations

App: made with Ionic v4 | Server: Django 2.2.4

Front side attempts

Main request method:

const httpOptions = {
    headers: new HttpHeaders({
        'Content-Type':  'application/json',
        'Accept': 'application/json',
    }),
    requestType: 'application/octet-stream'
};

this.http.post("http://127.0.0.1:8000/converter2/", file, httpOptions)
.pipe(
    finalize(() => {
        loader.dismiss();
    })
)
.subscribe(data => {
    console.log(data['body']);
}, error => {
    console.log(error);
    console.log(error.error.text)
});

Attempts:

With the method above I receive this error:

Error number 1 -> SyntaxError: Unexpected token P in JSON at position 0 at JSON.parse

I'm receiving this error because the http response, by default, is trying to parse the response. I read the documentation of HttpClient, but don't say much about receiving zip files.

I see some answers, like this one and this too, suggesting to add the { responseType: 'blob' } or { responseType: 'text' }. Dong this I receive another error:

Error number 2 -> 415 Unsupported Media Type

Trying to send requestType as 'application/zip' or 'application/octet-stream' returns the Error number 1. I tried also to change the 'Accept' to these values, resulting in:

Error number 3 -> 406 Could not satisfy the request Accept header

As I said before, I can access the zip file through console.log(error.error.text), but I want to receive it correctly, not as an error.

Server side attempts

Main response method:

# Return processed file
zip_file = open(zipfiles_folder + 'myfile.zip', 'rb')
return_response = HttpResponse(zip_file, content_type='application/force-download')
return_response['Content-Disposition'] = 'attachment; filename="%s"' % 'myfile.zip'
return return_response

Attempts:

Now I tried to change the response content_type, without success, as the following:

  1. content_type='application/zip'
  2. content_type='application/octet-stream'

Then I tried to follow some suggestions, again without success:

zip_file = open(zipfiles_folder + 'myfile.zip', 'rb')
return_response = HttpResponse(zip_file, content_type='application/force-download')
return_response['Content-Disposition'] = 'attachment; filename="%s"' % 'myfile.zip'
return_response['Content-Description'] = 'File Transfer'
return_response['Content-Transfer-Enconding'] = 'binary'
return return_response

The ZIP response (not exactly this, but pretty similar):

PK     B�O<�'�   �      filename.shp  '
                       N�        `�_I�*-!L��;�  `�YI�ޞ�b��;�                                      
     `�YI�ޞ�b��;�      
      `�_I�*-!L��;�PK     B�O�f#t   t      filename.shx  '
                       :�        `�_I�*-!L��;�  `�YI�ޞ�b��;�                                   2   
   @   
PK     B�Opk��Z   Z      filename.dbfw   A                   W  FID        N                   
           0           1PK     B�O�Z��  �     filename.prjPROJCS["SIRGAS_2000_UTM_Zone_22S",GEOGCS["GCS_SIRGAS_2000",DATUM["D_SIRGAS_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",10000000.0],PARAMETER["Central_Meridian",-51.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]PK      B�O<�'�   �              ��    filename.shpPK      B�O�f#t   t              ���   filename.shxPK      B�Opk��Z   Z              ��d  filename.dbfPK      B�O�Z��  �             ���  filename.prjPK      �   �   
leonardofmed
  • 842
  • 3
  • 13
  • 47
  • Did you solve this @leonardofmed? I'm running into a similar issue and haven't been able to find a solution after researching for 5h – EnriqueH Jun 25 '20 at 18:45
  • Unfortunately not, after a few days trying to find the solution I ended up giving priority to other functions and never came back to this problem. If you find it, please share it here. – leonardofmed Jun 25 '20 at 18:50
  • OK so I solved it. My problem is that I was adding the `zipfile.ZIP_DEFLATED` flag when writing the files into the zip file. Seems like it could be your problem as your ZIP response looks like your binary is actually a folder and not a zip file. One way of checking what I'm saying is generating the request from postman and then hitting on "Save response" > "Save to a file". Then it will appear as a folder in your disk, in which case we share the same problem. – EnriqueH Jun 25 '20 at 20:41
  • did you try response format as follows ? var reqOption = { headers: { --- }, responseType: 'arraybuffer' }; – Anil Dec 16 '20 at 10:31

1 Answers1

1

you can use request module to get a zip file from a url

import requests
url = 'https://www2.census.gov/geo/tiger/GENZ2017/shp/cb_2017_02_tract_500k.zip'
target_path = 'alaska.zip'

response = requests.get(url, stream=True)
handle = open(target_path, "wb")
for chunk in response.iter_content(chunk_size=512):
    if chunk:  # filter out keep-alive new chunks
        handle.write(chunk)
handle.close()

Here the zip is downloaded and serve from the url and will save in directory in name of 'alaska.zip' .

Beside being you can visit this answer

Sayan
  • 93
  • 3
  • 9
  • Thank you for the answer, but I don't need do get the zip from anywhere. I have created the one I need inside the server. I just want to send it back to the app as a response, not as a new request. – leonardofmed Aug 02 '19 at 19:45
  • you can do something like response = HttpResponse(output.getvalue(), mimetype='application/zip') response['Content-Disposition'] = 'attachment; filename="yourzipfilename.zip"' return response [link](https://stackoverflow.com/questions/50952823/django-response-that-contains-a-zip-file-with-multiple-csv-files) have a look – Sayan Aug 02 '19 at 19:57
  • If you see my "main response method", in my post, you will see that this is exactly what I did. – leonardofmed Aug 02 '19 at 20:09