Upload multiple files in one query (jQuery / Python)

Hey guys. Basically, I need to create a way for the user to open a web page, select from the list of checkboxes in the form, and after submitting the form, upload all these files.

Here are the restrictions imposed on me by the client:

  • The platform is primarily mobile devices.
  • There are no zip files (since we cannot assume that the mobile device can handle zip codes)
  • Files MUST be downloaded, not streamed.

So, I created a web application using XHTML / CSS w / jQuery Mobile 1.0a3 on the interface and Apache w / Python 2.6 on the internal server. The target files to be downloaded are .mp3 files.

I managed to achieve the desired effect on the desktop using hidden iframes transferred from the server and downloaded by jQuery via AJAX ... but it does not work in the default Android browser or in the Dolphin browser.

I made sure my Apache configurator will force the loading behavior:

<Files *.mp3> ForceType application/octet-stream Header set Content-Disposition attachment </Files> 

In addition, the Apache header module is included (required for the "Header set" configuration parameter), so the problem does not occur.

I make an AJAX call on the server with all the selected elements as parameters, and when the server reads an array of elements, it will query the database for information about each element (for example, the URL of each mp3 file), then an iframe code is created on the server for each mp3 file, and then sent back to the jQuery $.load() function to load new frames (that load mp3).

Without inserting too much code, here is a very short test case of what I am doing:

Server side

 def download(req): resultDiv = """<div id="downloads">""" queryIds = [] for element in req.form: # "element" contains the id number that matches database record trackId = re.match('^track(\d+)', element).group(1) queryIds.append(trackId) conn = MySQLdb.connect(host='localhost', user='fake', passwd='fake', db='fake') cursor = conn.cursor() buildQuery = """\ SELECT filePath FROM tracks WHERE trackNum in (""" buildQuery += ','.join(queryIds) buildQuery += ')' cursor.execute(buildQuery) downloadRows = cursor.fetchall() for track in downloadRows: resultDiv += """ <iframe src="%s"></iframe> """ % track[0] return resultDiv 

Client side

 <!DOCTYPE html> <html> <head> <!-- INCLUDES FOR JQUERY MOBILE AND JQUERY --> <style type="text/css"> .invisible { display: none; } </style> <script type="text/javascript"> $(document).ready(function() { $('#albumForm').submit(function(e) { e.preventDefault(); // this will hold the selected items on the form selTracks = {}; $('#trackList').find(':checked').each(function() { selTracks[this.id] = 'on'; }); // load the iframes into a 'div' set aside for that purpose $('#results').load('control.py/download #tracks', selTracks); }); }); </script> </head> <body> <div data-role='page' id='page'> <div data-role='header' id='header'> </div> <div data-role='content' id='content'> <div id='container'> <form id='albumForm'> <div data-role='controlgroup' data-role='fieldcontain'> <input type='checkbox' name='track1' id='track1' /> <label for='track1' id='track1label'>Track 1</label> <input type='checkbox' name='track2' id='track2' /> <label for='track2' id='track2label'>Track 2</label> <input type='checkbox' name='track3' id='track3' /> <label for='track3' id='track3label'>Track 3</label> <input type='submit' id='downloadButton' value='Download' /> </div> </form> </div> <div id='results' class='invisible'> </div> </div> <div data-role='footer' id='footer'> </div> </div> </body> </html> 

Sorry, the code is so general (and greatly abbreviated), but I am not authorized to publish the actual code (you know how it is). But that is basically the essence of it; I believe the problem lies somewhere in the interpretation of the mobile browser, or perhaps in the HTTP headers? This WORKS in Chrome and Firefox on the desktop, and it really works exactly as expected in Fennec for Android (it downloads all files without further interaction and just displays them in the notification panel). I just can't assume everyone uses Fennec (which they don’t do, LOL).

In addition to the above, I tried the following (which everything worked on the desktop, but not on the mobile device):

  • JSON is returned from the server, and iframes created on the client using jQuery
  • JSON is returned from the server, and for a loop, to call window.open() for each URL
  • JSON is back from the server, and the <a> tags created by jQuery and click() running
  • Use different DOCTYPE

Here is what I tried, that didn't work either on the desktop or on the mobile device:

  • Modification of location.href or window.location (can do this only once, obviously)
  • Calling req.sendfile() on the server (maybe I'm doing it wrong?)
  • Returning multipart / form data and binary data with a given border from the server (VERY randomly, and maybe I'm doing it wrong too?)

Still no joy; What can I lose?

PS Please do not flame me for using hidden iframes ...

EDIT: I will even go with another native browser protocol that I can configure on a server, such as FTP. Any ideas are welcome.

UPDATE: I am trying to initiate an FTP connection with a client on the server and run "mget". I know net2ftp can do this ... now to figure it out;) Still new ideas.

+4
source share
1 answer

This is a client limit. There is a parallel load limit for each domain. Try using files from different domains, say d1.example.com and d2.example.com. All of them can be served from the same virtual host:

 <VirtualHost *:80> ServerName example.com ServerAlias d1.example.com d2.example.com ... </VirtualHost> 
0
source

Source: https://habr.com/ru/post/1345932/


All Articles