Привет, ребята.По сути, мне нужно создать для пользователя способ открывать веб-страницу, выбирать из списка флажков в форме и после отправки формы загружать все эти файлы вместе.
Вотограничения, наложенные на меня клиентом:
- Платформа в основном для мобильных устройств
- Нет файлов ZIP (поскольку мы не можем предположить, что мобильное устройство может обрабатывать почтовые индексы)
- Файлы ДОЛЖНЫ быть загружены, а не потоковыми
Поэтому я создал веб-приложение, используя XHTML / CSS w / jQuery Mobile 1.0a3 на внешнем интерфейсе и Apache w / Python 2.6 на внутреннем.Целевые файлы, которые будут загружены, - это файлы .mp3.
Мне удалось выполнить желаемый эффект на рабочем столе, используя скрытые фреймы, передаваемые с сервера и загружаемые с помощью jQuery через AJAX ... но это не так.не работает в браузере Android по умолчанию или в браузере Dolphin.
Я убедился, что мой конфиг Apache будет вызывать поведение при загрузке:
<Files *.mp3>
ForceType application/octet-stream
Header set Content-Disposition attachment
</Files>
Кроме того, модуль Apache "headers" включен (необходим дляПараметр конфигурации "Header set"), так что это не проблема.
Я выполняю AJAX-вызов на сервер со всеми выбранными элементами в качестве параметров, и когда сервер читает массив элементов, он запрашиваетбаза данных для информации о каждом элементе (например, URL каждого mp3-файла).Затем код iframe создается в бэкэнде для каждого mp3-файла и затем отправляется обратно в функцию $.load()
jQuery для загрузки новых iframes (загружающих mp3-файлы).
Не вставляя слишком много кода, вот оченькраткий тестовый пример того, что я делаю:
на стороне сервера
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
на стороне клиента
<!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>
Извините, код настолько общий (и значительно сокращен), но я не уполномочен публиковать реальный код (вы знаете, как он).Но это в основном суть этого;Я считаю, что проблема кроется где-то в интерпретации мобильного браузера или где-то в заголовках HTTP?Это работает в Chrome и Firefox на рабочем столе и фактически работает точно так же, как и ожидалось в Fennec для Android (он загружает все файлы без дальнейшего взаимодействия и просто отображает их в панели уведомлений).Я просто не могу предположить, что все используют Fennec (а это не так, смеется).
В дополнение к вышесказанному, я попробовал следующее (которые все работали на настольном компьютере, но не на мобильном):
- JSON возвращается с сервера, а iframes, созданные на клиенте с помощью jQuery
- JSON, возвращаются с сервера и цикл for для вызова
window.open()
для каждого URL - JSON вернулся с сервера, и
<a>
теги, созданные jQuery и click()
сработали - Использовать разные DOCTYPEs
Вот что я пробовал, но это неработать на настольном компьютере или на мобильном устройстве:
- Изменение
location.href
или window.location
(очевидно, это можно сделать только один раз) - Вызов
req.sendfile()
на сервере (возможно, яя делаю это неправильно?) - Возвращение multipart / form-data и сброс двоичных данных с заданной границей с сервера (ОЧЕНЬ грязно, и, возможно, я тоже делаю это неправильно?)
Все еще нет радости;Чего мне не хватать?
PS Пожалуйста, не сердитесь на меня за использование скрытых фреймов ...
РЕДАКТИРОВАТЬ: Я даже буду в порядке с другим родным протоколом браузера, который я могу настроитьна сервере, например FTP.Все идеи приветствуются.
ОБНОВЛЕНИЕ: Я пытаюсь установить FTP-соединение от клиента к серверу и запустить «mget».Я знаю, что net2ftp может сделать это ... теперь, чтобы понять это;) Все еще готов к новым идеям.