Он может быть разрешен ниже простым кодом с помощью Stream и Try в AbacusUtil :
Stream.of(accounts).filter(a -> Try.call(a::isActive)).map(a -> Try.call(a::getNumber)).toSet();
Раскрытие информации : Я разработчик AbacusUtil
.
Начиная с Safari 5 / Firefox 4, проще всего использовать класс FormData
:
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
Итак, теперь у вас есть объект FormData
, готовый к отправке вместе с XMLHttpRequest.
jQuery.ajax({
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
});
Обязательно установить параметр contentType
на false
, заставляя jQuery не добавлять к вам заголовок Content-Type
, иначе пограничная строка будет отсутствовать. Кроме того, вы должны оставить флаг processData
установленным как false, в противном случае jQuery попытается преобразовать ваш FormData
в строку, которая потерпит неудачу.
Теперь вы можете получить файл на PHP, используя:
$_FILES['file-0']
(Существует только один файл, file-0
, если вы не указали атрибут multiple
на входе файла, и в этом случае числа будут увеличиваться с каждым файлом.)
Использование эмуляции FormData для старых браузеров
var opts = {
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
};
if(data.fake) {
// Make sure no text encoding stuff is done by xhr
opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
opts.contentType = "multipart/form-data; boundary="+data.boundary;
opts.data = data.toString();
}
jQuery.ajax(opts);
Создание FormData из существующей формы
Вместо ручного итерации файлов FormData объект также может быть создан с содержимым существующего объекта формы:
var data = new FormData(jQuery('form')[0]);
Использовать собственный массив PHP вместо счетчика
Просто назовите ваши файловые элементы одинаковыми и запустите имя в скобках:
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file[]', file);
});
$_FILES['file']
будет массивом, содержащим поля для загрузки файлов для каждого загруженного файла. Я действительно рекомендую это по сравнению с моим первоначальным решением, поскольку его проще перебирать.
Просто хотел добавить немного к большому ответу Рафаэля. Вот как получить PHP для создания того же $_FILES
, независимо от того, используете ли вы JavaScript.
HTML-форма:
<form enctype="multipart/form-data" action="/test.php"
method="post" class="putImages">
<input name="media[]" type="file" multiple/>
<input class="button" type="submit" alt="Upload" value="Upload" />
</form>
PHP создает это $_FILES
, когда представленный без JavaScript:
Array
(
[media] => Array
(
[name] => Array
(
[0] => Galata_Tower.jpg
[1] => 518f.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpIQaOYo
[1] => /tmp/phpJQaOYo
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 258004
[1] => 127884
)
)
)
Если вы делаете прогрессивное повышение, используя JS Raphael для отправки файлов ...
var data = new FormData($('input[name^="media"]'));
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
data.append(i, file);
});
$.ajax({
type: ppiFormMethod,
data: data,
url: ppiFormActionURL,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}
});
... это то, что PHP $_FILES
массив выглядит, после использования этого JavaScript для отправки:
Array
(
[0] => Array
(
[name] => Galata_Tower.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpAQaOYo
[error] => 0
[size] => 258004
)
[1] => Array
(
[name] => 518f.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpBQaOYo
[error] => 0
[size] => 127884
)
)
Это хороший массив, и на самом деле некоторые люди трансформируют $_FILES
в, но я считаю полезным работать с тем же $_FILES
, независимо от того, был ли JavaScript использован для отправки. Итак, вот некоторые незначительные изменения в JS:
// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );
// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
data.append(fileInputName+'['+i+']', file);
});
(14 апреля 2017 г. edit: я удалил элемент формы из конструктора FormData (), который исправил этот код в Safari.)
Этот код выполняет две функции.
input
, что делает HTML более удобным. Теперь, пока form
имеет класс putImages, все остальное заботится автоматически. То есть, у input
не должно быть специального имени. С этими изменениями, отправляя с помощью JavaScript, теперь создается точно такой же массив $_FILES
, что отправляется с простым HTML.
Посмотрите на мой код, он выполняет эту работу для меня
$( '#formId' )
.submit( function( e ) {
$.ajax( {
url: 'FormSubmitUrl',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
Я только что создал эту функцию на основе некоторой информации, которую я прочитал.
Используйте ее, как с помощью .serialize()
, вместо этого просто поставьте .serializefiles();
. Работа в моих тестах.
//USAGE: $("#form").serializefiles();
(function($) {
$.fn.serializefiles = function() {
var obj = $(this);
/* ADD FILE TO PARAM AJAX */
var formData = new FormData();
$.each($(obj).find("input[type='file']"), function(i, tag) {
$.each($(tag)[0].files, function(i, file) {
formData.append(tag.name, file);
});
});
var params = $(obj).serializeArray();
$.each(params, function (i, val) {
formData.append(val.name, val.value);
});
return formData;
};
})(jQuery);
var data = $("#avatar-form").serializefiles();
, отправляя это через параметр данных ajax и анализируя с помощью выраженного грозного: form.parse(req, function(err, fields, files){
благодарим вас за этот фрагмент кода :)
– SchurigH
19 November 2013 в 23:53
Класс FormData работает, однако в iOS Safari (по крайней мере, на iPhone) я не смог использовать решение Рафаэля Швайкерта как есть.
Mozilla Dev имеет приятную страницу on манипулируя объектами FormData .
Итак, добавьте пустую форму где-нибудь на вашей странице, указав enctype:
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>
Затем создайте объект FormData как:
var data = new FormData($("#fileinfo"));
и продолжайте, как в коде Рафаэля .
Если ваша форма определена в вашем HTML, проще передать форму в конструктор, чем для итерации и добавления изображений.
$('#my-form').submit( function(e) {
e.preventDefault();
var data = new FormData(this); // <-- 'this' is your form element
$.ajax({
url: '/my_URL/',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
...
Один из них, на который я столкнулся сегодня, думаю, стоит обратить внимание на эту проблему: если URL-адрес для вызова ajax перенаправлен, заголовок для типа контента: «multipart / form-data» может быть потерян.
Например, я отправлял сообщение в http://server.com/context?param=x
. На вкладке «Сеть» в Chrome я увидел правильный multipart заголовок для этого запроса, но затем перенаправление 302 на http://server.com/context/?param=x (обратите внимание на слэш после контекста)
Во время перенаправления multipart заголовок был потерян. Убедитесь, что запросы не перенаправляются, если эти решения не работают для вас.
Старые версии IE не поддерживают FormData (Полный список поддержки браузера для FormData находится здесь: https://developer.mozilla.org/en-US/docs/Web/API/FormData ) .
Либо вы можете использовать плагин jquery (для ex, http://malsup.com/jquery/form/#code-samples ), либо вы можете использовать IFrame based решение для отправки данных многочастной формы через ajax: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
Все вышеприведенные решения выглядят хорошо и элегантно, но объект FormData () не ожидает какого-либо параметра, но использует append () после его создания, как то, что было написано выше:
formData.append (val.name, val.value);
data.fake
и установить свойствоcontentType
вручную, а также переопределить xhr для использованияsendAsBinary()
. – Raphael Schweikert 24 August 2011 в 09:01jQuery
или классFormData
, и вы спрашиваете меня в контексте вопроса, специфичного для jQuery, и ответа, специфичного для использования FormData? Извините, но я не думаю, что могу помочь вам там ... – Raphael Schweikert 19 April 2012 в 10:44application/x-www-form-urlencoded
. Есть ли способ использоватьmultipart/form-data
вместо этого? – Timmmm 6 April 2013 в 21:43multipart/form-data
. Использованиеapplication/x-www-form-urlencoded
не сработает. – Raphael Schweikert 7 April 2013 в 09:57