Eu tenho um problema ao enviar um arquivo para um script PHP ao lado do servidor usando a função ajax do jQuery. É possível obter a lista de arquivos, $('#fileinput').attr('files')
mas como é possível enviar esses dados para o servidor? A matriz resultante ( $_POST
) no script php-server do servidor é 0 ( NULL
) ao usar a entrada de arquivo.
Eu sei que é possível (embora eu não tenha encontrado nenhuma solução jQuery até agora, apenas o código Prototye ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html )) )
Isso parece ser relativamente novo; portanto, não mencione o upload de arquivos seria impossível via XHR / Ajax, porque definitivamente está funcionando.
Preciso que a funcionalidade do Safari 5, FF e Chrome seja legal, mas não essencial.
Meu código por enquanto é:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
$(':file')
para selecionar todos os arquivos de entrada. É um pouco mais simples.Respostas:
A partir do Safari 5 / Firefox 4, é mais fácil usar a
FormData
classe:Então agora você tem um
FormData
objeto, pronto para ser enviado junto com o XMLHttpRequest.É imperativo que você defina a
contentType
opçãofalse
, forçando o jQuery a não adicionar umContent-Type
cabeçalho para você, caso contrário, a cadeia de limite estará ausente. Além disso, você deve deixar oprocessData
sinalizador definido como falso, caso contrário, o jQuery tentará converter seuFormData
em uma string, o que falhará.Agora você pode recuperar o arquivo no PHP usando:
(Existe apenas um arquivo, a
file-0
menos que você tenha especificado omultiple
atributo na entrada do arquivo; nesse caso, os números serão incrementados a cada arquivo.)Usando a emulação FormData para navegadores mais antigos
Criar FormData a partir de um formulário existente
Em vez de iterar manualmente os arquivos, o objeto FormData também pode ser criado com o conteúdo de um objeto de formulário existente:
Use uma matriz nativa do PHP em vez de um contador
Apenas nomeie os elementos do arquivo da mesma forma e termine o nome entre colchetes:
$_FILES['file']
será uma matriz que contém os campos de upload de arquivos para cada arquivo carregado. Na verdade, eu recomendo isso na minha solução inicial, pois é mais simples de repetir.fonte
data.fake
e definir acontentType
propriedade manualmente, bem como substituir o xhr para usarsendAsBinary()
.jQuery
nem aFormData
classe e está me perguntando no contexto de uma pergunta específica para jQuery e uma resposta específica para usar FormData? Sinto muito, mas eu não acho que posso ajudá-lo lá ...application/x-www-form-urlencoded
. Existe uma maneira de usarmultipart/form-data
?multipart/form-data
. Usarapplication/x-www-form-urlencoded
não funcionaria.Só queria acrescentar um pouco à grande resposta de Raphael. Veja como obter o PHP para produzir o mesmo
$_FILES
, independentemente de você usar JavaScript para enviar.Formulário HTML:
O PHP produz isso
$_FILES
, quando enviado sem JavaScript:Se você fizer aprimoramento progressivo, use o JS do Raphael para enviar os arquivos ...
... é assim que a
$_FILES
matriz do PHP se parece, depois de usar esse JavaScript para enviar:Essa é uma boa matriz e, na verdade, o que algumas pessoas transformam
$_FILES
, mas acho útil trabalhar com a mesma$_FILES
, independentemente se o JavaScript foi usado para enviar. Então, aqui estão algumas pequenas alterações no JS:(Edição de 14 de abril de 2017: removi o elemento de formulário do construtor de FormData () - que corrigiu esse código no Safari.)
Esse código faz duas coisas.
input
atributo name automaticamente, tornando o HTML mais sustentável. Agora, desde queform
a classe putImages, todo o resto é resolvido automaticamente. Ou seja, ainput
necessidade não precisa ter nenhum nome especial.Com essas alterações, o envio com JavaScript agora produz exatamente a mesma
$_FILES
matriz que o envio com HTML simples.fonte
Olhe para o meu código, ele faz o trabalho para mim
fonte
Acabei de criar essa função com base em algumas informações que li.
Use-o como usar
.serialize()
, basta colocar.serializefiles();
.Trabalhando aqui nos meus testes.
fonte
var data = $("#avatar-form").serializefiles();
o envio desta via ajax parâmetro de dados e análise com formidável expressa:form.parse(req, function(err, fields, files){
obrigado por isso trecho de código :)Se o seu formulário estiver definido no HTML, é mais fácil passar o formulário para o construtor do que iterar e adicionar imagens.
fonte
A resposta de Devin Venable estava próxima do que eu queria, mas eu queria uma que funcionasse em vários formulários e usasse a ação já especificada no formulário para que cada arquivo fosse para o lugar certo.
Eu também queria usar o método on () do jQuery para evitar o uso de .ready ().
Isso me levou a isso: (substitua formSelector pelo seu seletor jQuery)
fonte
Hoje em dia você nem precisa do jQuery :) buscar a tabela de suporte à API
fonte
fetch
, consulte a compatibilidade: developer.mozilla.org/pt-BR/docs/Web/API/…:-|
A classe FormData funciona, no entanto, no iOS Safari (pelo menos no iPhone), não consegui usar a solução de Raphael Schweikert como está.
O Mozilla Dev tem uma boa página sobre como manipular objetos FormData .
Portanto, adicione um formulário vazio em algum lugar da sua página, especificando o enctype:
Em seguida, crie o objeto FormData como:
e proceda como no código de Rafael .
fonte
Uma dica que encontrei hoje, acho que vale a pena apontar relacionada a esse problema: se o URL da chamada ajax for redirecionado, o cabeçalho do tipo de conteúdo: 'multipart / form-data' pode ser perdido.
Por exemplo, eu estava postando em http://server.com/context?param=x
Na guia de rede do Chrome, vi o cabeçalho de várias partes correto para essa solicitação, mas um redirecionamento 302 para http://server.com/context/?param=x (observe a barra após o contexto)
Durante o redirecionamento, o cabeçalho de várias partes foi perdido. Verifique se as solicitações não estão sendo redirecionadas se essas soluções não estiverem funcionando para você.
fonte
Todas as soluções acima são boas e elegantes, mas o objeto FormData () não espera nenhum parâmetro, mas usa append () após instancia-lo, como o que foi escrito acima:
formData.append (val.name, val.value);
fonte
Se o arquivo de entrada
name
indica um array e bandeirasmultiple
, e você analisar o todoform
comFormData
, não é necessário de forma iterativaappend()
os arquivos de entrada.FormData
manipulará automaticamente vários arquivos.Observe que um regular
button type="button"
é usado, nãotype="submit"
. Isso mostra que não há dependência do usosubmit
para obter essa funcionalidade.A
$_FILES
entrada resultante é assim nas ferramentas de desenvolvimento do Chrome:Nota: Há casos em que algumas imagens são carregadas muito bem quando carregadas como um único arquivo, mas elas falham quando carregadas em um conjunto de vários arquivos. O sintoma é que o PHP relata vazio
$_POST
e$_FILES
sem o AJAX lançando erros. O problema ocorre com o Chrome 75.0.3770.100 e o PHP 7.0. Apenas parece acontecer com 1 dentre várias dezenas de imagens no meu conjunto de testes.fonte
As versões anteriores do IE não oferecem suporte ao FormData (a lista completa de suporte do navegador para FormData está aqui: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
Você pode usar um plug-in jquery (por exemplo, http://malsup.com/jquery/form/#code-samples ) ou usar a solução baseada em IFrame para postar dados de formulário com várias partes por meio do ajax: https: // developer. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
fonte
PHP
jQuery e formulário HTML
fonte
fonte