Como converter o objeto FormData HTML5 para JSON? Sem Jquery e manipulando propriedades aninhadas em FormData como um objeto.
javascript
form-data
Leonardo Villela
fonte
fonte
JSON.stringify()
ajuda? Talvez você tente consertar algo que pode ser feito de outra maneira?Respostas:
Você também pode usar
forEach
noFormData
objeto diretamente:ATUALIZAR:
E para quem prefere a mesma solução com as funções de seta ES6 :
ATUALIZAÇÃO 2:
E para aqueles que desejam suporte para listas de seleção múltipla ou outros elementos de formulário com valores múltiplos (já que existem tantos comentários abaixo da resposta a respeito desse problema, adicionarei uma possível solução) :
Aqui está um Fiddle demonstrando o uso desse método com uma lista de seleção múltipla simples.
ATUALIZAÇÃO 3:
Como uma nota lateral para quem vai parar aqui, caso o objetivo de converter os dados do formulário para json seja enviá-los por meio de uma solicitação HTTP XML para um servidor, você pode enviar o
FormData
objeto diretamente sem convertê-lo. Simples assim:Consulte também Usando objetos FormData no MDN para referência :
ATUALIZAÇÃO 4:
Conforme mencionado em um dos comentários abaixo, minha resposta o
stringify
método JSON não funcionará fora da caixa para todos os tipos de objetos. Para obter mais informações sobre quais tipos são suportados, gostaria de consultar a seção Descrição na documentação do MDN deJSON.stringify
.Na descrição também é mencionado que:
Isso significa que você pode fornecer seu próprio
toJSON
método de serialização com lógica para serializar seus objetos personalizados. Assim, você pode construir suporte de serialização de forma rápida e fácil para árvores de objetos mais complexas.fonte
<SELECT MULTIPLE>
e<INPUT type="checkbox">
com o mesmo nome, convertendo o valor em um array.JSON.stringify(Object.fromEntries(formData));
é muito mais agradávelEm 2019, esse tipo de tarefa ficou super fácil.
Object.fromEntries
: Compatível com Chrome 73+, Firefox 63+, Safari 12.1fonte
<select multiple>
ou<input type="checkbox">
😞JSON.stringify(Object.fromEntries(formData.entries()));
Esta é uma maneira de fazer isso em um estilo mais funcional, sem o uso de uma biblioteca.
Exemplo:
fonte
Se você tiver várias entradas com o mesmo nome, por exemplo, se você usar
<SELECT multiple>
ou tiver várias<INPUT type="checkbox">
com o mesmo nome, você precisa cuidar disso e fazer uma matriz do valor. Caso contrário, você obtém apenas o último valor selecionado.Aqui está a variante ES6 moderna:
Código ligeiramente mais velho (mas ainda não é suportado pelo IE11, uma vez que não suporta
ForEach
ouentries
onFormData
)fonte
Você pode fazer isso usando o objeto FormData () . Este objeto FormData será preenchido com as chaves / valores atuais do formulário usando a propriedade name de cada elemento para as chaves e seu valor enviado para os valores. Ele também codificará o conteúdo de entrada do arquivo.
Exemplo:
fonte
for (const [key, value] of formData.entries())
Função fácil de usar
Eu criei uma função para isso
Exemplo de uso
Neste código, criei uma variável JSON vazia usando o
for
loop. Useikey
s do objeto formData para Chaves JSON em cada Itração.Você encontra este código na minha biblioteca JS no GitHub Sugira-me se precisar de melhorias Coloquei o código aqui https://github.com/alijamal14/Utilities/blob/master/Utilities.js
fonte
<select multiple>
ou<input type="checkbox">
.Este post já tem um ano ... mas, realmente, gostei muito da resposta do ES6 @dzuc. No entanto, está incompleto por não ser capaz de lidar com várias seleções ou caixas de seleção. Isso já apontou e soluções de código foram oferecidas. Acho que são pesados e não otimizados. Então, escrevi 2 versões baseadas em @dzuc para lidar com esses casos:
Versão Hotshot de uma linha:
[]
sufixo.Versão Hotshot de uma linha:
Desde a última vez que escrevi o segundo caso anterior, no trabalho surgiu um caso em que o formulário do PHP tinha caixas de seleção em vários níveis. Eu escrevi um novo caso para apoiar o caso anterior e este. Criei um trecho para melhor mostrar este caso, o resultado mostrado no console para este demo, modifique isso de acordo com sua necessidade. Tentei otimizá-lo o melhor que pude sem comprometer o desempenho, no entanto, comprometeu alguma legibilidade humana. Ele aproveita que os arrays são objetos e as variáveis que apontam para os arrays são mantidas como referência. Nenhum figurão para este, fique à vontade.
fonte
Array.from(fd).reduce((obj, [k, v]) => ({...obj, [k]: v}), {});
versão principal es2018O método FormData
.entries
e afor of
expressão não são suportados no IE11 e Safari.Aqui está uma versão mais simples para suportar Safari, Chrome, Firefox e Edge
Aviso: esta resposta não funciona no IE11.
FormData não tem um
forEach
método no IE11.Ainda estou procurando uma solução final para oferecer suporte a todos os principais navegadores.
fonte
Se você estiver usando lodash, isso pode ser feito de forma concisa com
fromPairs
fonte
Se você precisar de suporte para serializar campos aninhados, semelhante a como o PHP lida com campos de formulário, você pode usar a seguinte função
fonte
Você pode tentar isso
fonte
Mesmo que a resposta de @dzuc já seja muito boa, você pode usar a desestruturação de array (disponível em navegadores modernos ou com o Babel) para torná-la ainda mais elegante:
fonte
One-liner abusivo!
Hoje eu aprendi que o firefox tem suporte a propagação de objetos e desestruturação de array!
fonte
Se os itens a seguir atendem às suas necessidades, você está com sorte:
[['key','value1'], ['key2','value2']
(como o que FormData oferece) em um objeto chave-> valor como{key1: 'value1', key2: 'value2'}
e convertê-lo em uma string JSON.Aqui está o código de que você precisa:
Espero que isso ajude alguém.
fonte
Não vi menções ao método FormData.getAll até agora.
Além de retornar todos os valores associados a uma determinada chave de dentro de um objeto FormData, torna-se muito simples usar o método Object.fromEntries conforme especificado por outros aqui.
Snippet em ação
fonte
Funcionou para mim
fonte
<select multiple>
ou<input type="checkbox">
No meu caso, os dados eram dados, a base de incêndio esperava um objeto, mas os dados contêm o objeto, bem como todos os outros materiais, então tentei data.value funcionou !!!
fonte
Estou chegando tarde aqui. No entanto, fiz um método simples que verifica a entrada type = "caixa de seleção"
Espero que isso ajude mais alguém.
fonte
Você pode fazer esse trabalho facilmente, sem usar nada especial. Um código como o abaixo será suficiente.
fonte