Hey men. Essentially, I have to produce a method for a person to spread out an internet page, select from a listing of checkboxes inside a form, and when the shape is posted, download all individuals files together.

Listed here are the limitations enforced on me through the client:

  • Platform is mainly mobile products
  • No zip files (since we can't think that the mobile device are designed for zip fasteners)
  • Files Should be downloaded, not streamed

And So I produced an internet application using XHTML/CSS w/ jQuery Mobile 1.0a3 around the front-finish and Apache w/ Python 2.6 around the back-finish. The prospective files that'll be downloaded are .mp3 files.

I've effectively handled to do the preferred impact on the desktop using hidden iframes passed in the server and loaded by jQuery via AJAX... however it does not focus on the default Android browser or Dolphin browser.

I ensured my Apache config will pressure download behavior:

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

Also, Apache's "headers" module is enabled (required for the "Header set" config parameter), so that isn't an problem.

I make an AJAX call towards the server with all the selected products as parameters, so when the server reads the variety of products, it'll query the database for details about the items (like the Link to each mp3 file). Then your iframe code is produced around the after sales for every mp3 file after which delivered back to jQuery's $.load() function to load the brand new iframes (which downloads the tunes).

Without pasting an excessive amount of code, here is a very short test situation of the items 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)

    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 += ')'

    downloadRows = cursor.fetchall()

    for track in downloadRows:
        resultDiv += """
            <iframe src="%s"></iframe>
        """ % track[0]

    return resultDiv

Client Side

<!DOCTYPE html>
        <style type="text/css">
            .invisible {
                display: none;
        <script type="text/javascript">
            $(document).ready(function() {
                $('#albumForm').submit(function(e) {

                    // 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);
        <div data-role='page' id='page'>
            <div data-role='header' id='header'>
            <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 id='results' class='invisible'>
            <div data-role='footer' id='footer'>

Sorry the code is really generic (and considerably reduced), but I am not approved to publish the particular code (you are aware how it's). But this really is essentially the gist from it In my opinion the issue lies somewhere in both the mobile browser's interpretation, or possibly within the HTTP headers somewhere? This WORKS in Chrome and Opera around the desktop, also it really works just as expected in Fennec for Android (it downloads all of the files without any further interaction and merely shows them within the notification bar). I simply can't assume everyone's using Fennec (which they are not, lol).

Additionally towards the above, I have attempted the next (that have all done desktop but this is not on mobile):

  • JSON came back in the server, and iframes produced around the client by jQuery
  • JSON came back in the server, along with a for-loop to call window.open() for every URL
  • JSON came back in the server, and <a> tags produced by jQuery along with a click() triggered
  • Use different DOCTYPEs

Some tips about what I attempted that did not focus on either desktop or mobile:

  • Modifying location.href or window.location (are only able to get it done once, clearly)
  • Calling req.sendfile() around the server (maybe I am doing the work wrong?)
  • Coming back multipart/form-data and dumping binary data having a set boundary in the server (VERY untidy, and perhaps I am also doing that one wrong?)

Still no pleasure What could I be missing?

P.S. Do not flame me for implementing hidden iframes...

EDIT: I'll be also okay choosing another native browser protocol will be able to setup around the server, for example FTP. All ideas are welcome.

UPDATE: Am attempting to initiate an FTP connection in the client towards the server and operate a "mget". I understand net2ftp can perform this... now to decipher it ) Still up for brand new ideas.