Есть ли обходные пути для ошибки загрузки нескольких файлов Safari HTML5?
После нескольких недель настройки я наконец сдался. Я просто не мог исправить загрузку нескольких файлов в Safari, что меня очень беспокоило, потому что мой код работал отлично, как и в других браузерах, кроме Safari. Тогда я только недавно обнаружил, что проблема не в моем коде. Это ошибка Safari. Safari 5.1.+ Не может прочитать множественный атрибут html5 (или что-то в этом роде). Таким образом, пользователи не могут использовать функцию множественной загрузки, НО, могут правильно загрузить один файл.
Несколько ссылок, которые обсуждают проблему:
https://github.com/moxiecode/plupload/issues/363
проблема размера входного файла в Safari для выбора нескольких файлов
Кажется, что эта ошибка существует уже довольно давно. Так что мне было интересно, есть ли обходные пути, доступные для этого в тот момент, о которых некоторые из вас, возможно, знают? Потому что я не могу найти ни одного. Единственный доступный вариант, который я нашел, - НЕ использовать несколько атрибутов для пользователей Safari 5.1.+. У вас, ребята, есть идеи получше?
ОБНОВИТЬ
Safari 5.1.7 - последняя версия Apple, созданная для ОС Windows. Они не продолжали собирать текущие версии Safari для Windows. Поиск исправления для этой ошибки для меня не является необходимым, поскольку пользователи Real Safari обновляются до последней версии браузера (без фактов), и просто дают отдельную загрузку для тех, кто все еще использует эту устаревшую версию, чтобы не жертвовать современной особенности вашего приложения.
3 ответа
Это старый вопрос, но... обходной путь типа взлома ниже.
Просто удалите несколько атрибутов для Safari, превратите их в младшего брата MSIE<=9 (не XHR).
Остальные браузеры не пострадают.
Когда Safari наконец решит проблему, все, что вам нужно сделать, это удалить этот hack::code и вернуться к стандартному входному коду.
вот стандартный пример ввода:
Решение jQuery:
Просто разместите его где-нибудь на странице, где у вас есть файлы для ввода тегов.
Вы можете прочитать больше здесь: Как обнаружить браузер Safari, Chrome, IE, Firefox и Opera?
$ (документ).ready(function () { if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')>0); $('FileUpload-вход.) RemoveAttr("несколько"). });
PHP решение
вам понадобится код для идентификатора браузера. Я использовал класс, который я получил в github (MIT), получите его здесь: https://github.com/gavroche/php-browser
$ files = ''; if (Browser:: getBrowser () === Browser:: SAFARI) { $ files = ''; } echo $ files
Это все.
Кажется, что есть еще одна проблема, которая может возиться. iOS Safari для загрузки нескольких файлов всегда использует имя "image.jpg" для всех загружаемых файлов. Может показаться, что только один файл загружен на стороне сервера, но это не то, что произошло: были загружены все файлы с одинаковым именем!
Итак, обходной путь приходит на стороне сервера: просто измените имя файла назначения на новое сгенерированное имя.
Я работаю с Flask и Python, поэтому я использую стандартную формулу.
@app.route("/upload",methods=['POST'])
def upload():
files = request.files.getlist('files[]')
for file in files:
if file and allowed_file(file.filename):
filename = generate_filename(file.filename)
file.save( os.path.join(app.config['UPLOAD_FOLDER'], new_album_id, filename))
return render_template('upload_ok.html')
куда generate_filaname
должна быть функция, которая создает новое имя файла с тем же расширением, что и исходное. Например:
def generate_filename(sample_filename):
# pick up extension from sample filename
ext = sample_filename.split(".")[-1]
name = ''.join( random.SystemRandom().choice(string.letters+string.digits) for i in range(16) )
return name + "." + ext
Конечно, то же самое можно сделать и в PHP.
Я столкнулся с проблемой image.jpg с asp.net. Это может принести пользу кому-то. Я добавлял неуникальный хеш к каждому файлу изображения, чтобы связать его с записью в БД. Прекрасно работает на любой платформе (в любом случае, наши пользователи), за исключением использования Safari. Я только что добавил хеш и уникальную трехзначную строку, которую я извлек из секундной части DateTime в строку:
if (!string.IsNullOrEmpty(ViewState["HashId"].ToString()))
{
string filepath = Server.MapPath("~/docs/");
HttpFileCollection uploadedFiles = Request.Files;
Span1.Text = string.Empty;
for (int i = 0; i < uploadedFiles.Count; i++)
{
HttpPostedFile userPostedFile = uploadedFiles[i];
try
{
if (userPostedFile.ContentLength > 0)
{
string timestamp = DateTime.UtcNow.ToString("fff",
CultureInfo.InvariantCulture);
//Span1.Text += "<u>File #" + (i + 1) + "</u><br>";
//Span1.Text += "File Content Type: " + userPostedFile.ContentType + "<br>";
//Span1.Text += "File Size: " + userPostedFile.ContentLength + "kb<br>";
//Span1.Text += "File Name: " + userPostedFile.FileName + "<br>";
userPostedFile.SaveAs(filepath + "\\" + ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName));
// Span1.Text += "Location where saved: " + filepath + "\\" + Path.GetFileName(userPostedFile.FileName) + "<p>";
InsertFilename("~/docs/" + ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName), ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName));
}
}
catch (Exception Ex)
{
Span1.Text += "Error: <br>" + Ex.Message;
}
}
BindImages();
SetAttchBitTrue();
Button4.Visible = true;
AttchStatus.Text = "This Record Has Attachments";
Button2.Visible = true;
Button3.Visible = true;
Panel1.Visible = false;
}
Может быть, и лучше, но у нас просто небольшое количество людей, загружающих одно - два, может быть, три изображения на запись в базе данных. Должно сработать.