O que significa o enctype= "multipart / form-data"?
o que significa {[[0]} num formulário HTML e quando devemos usá-lo?
9 answers
Quando você faz um pedido de POST, você tem que codificar os dados que formam o corpo do pedido de alguma forma.
Os formulários HTML fornecem três métodos de codificação.
-
application/x-www-form-urlencoded
(por omissão) multipart/form-data
text/plain
application/json
, mas isso foi abandonado.
(outras codificações são possíveis com requisições HTTP geradas usando outros meios que não um envio de formulário HTML. JSON é um formato comum para uso com serviços web e alguns ainda usar sabão.)
As especificidades dos formatos não importam para a maioria dos desenvolvedores. Os pontos importantes são:
- Nunca utilize
text/plain
.
Quando estás a escrever o código do lado do cliente:
- utilizar
multipart/form-data
quando a sua forma incluir quaisquer<input type="file">
elementos - caso contrário, pode usar
multipart/form-data
ouapplication/x-www-form-urlencoded
masapplication/x-www-form-urlencoded
será mais eficiente
Quando estiver a escrever o código do lado do servidor:
- usar um pré-escrito biblioteca de tratamento de formulários
A Maioria (como o Perl CGI->param
ou o exposto pelo PHP $_POST
superglobal) cuidará das diferenças para você. Não se incomode em tentar analisar a entrada raw recebida pelo servidor.
Às vezes você vai encontrar uma biblioteca que não pode lidar com ambos os formatos. No.a biblioteca mais popular da js para lidar com dados de formulários é body-parser que não consegue lidar com pedidos multipartidários (mas tem documentação que recomenda algumas alternativas que poder).
Se está a escrever (ou a depurar) uma biblioteca para analisar ou gerar os dados raw, então precisa de começar a preocupar-se com o formato. Talvez também queiras saber por interesse.
application/x-www-form-urlencoded
é mais ou menos o mesmo que uma string de consulta no final da URL.
multipart/form-data
é significativamente mais complicado, mas permite que arquivos inteiros sejam incluídos nos dados. Um exemplo do resultado pode ser encontrado na especificação HTML 4 .
text/plain
é introduzido pelo HTML 5 e só é útil para depuração de especificação: Eles não são de forma confiável interpretável por computador - e eu diria que os outros combinado com ferramentas (como Rede do Painel de em que o desenvolvedor de ferramentas da maioria dos navegadores) são melhores para isso).
Quando devemos usá-lo
A resposta do Quentin está correcta: use multipart/form-data
se o formulário contém um envio de ficheiro, e application/x-www-form-urlencoded
caso contrário, qual é o valor por omissão se omitir enctype
.
Eu vou para:
- adicione mais algumas referências HTML5
- explique porque {[65] } Ele tem razão com um exemplo de envio de formulário
Referências HTML5
Existem três possibilidades para:enctype
:
application/x-www-form-urlencoded
-
multipart/form-data
(pontos especícos para RFC7578) -
text/plain
. Isso não é "confiável interpretável por computador", por isso nunca deve ser usado na produção, e não vamos olhar mais adiante.
Como gerar os exemplos
Uma vez que você vê um exemplo de cada método, torna-se óbvio como eles funcionam, e quando você deve usar cada um.Você pode produzir exemplos utilizar:
-
nc -l
ou um servidor ECHO: servidor de teste HTTP que aceita pedidos de obtenção / publicação - um agente de utilizador como um browser ou cURL
Guarde o formulário num ficheiro mínimo .html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
<p><input type="text" name="text1" value="text default">
<p><input type="text" name="text2" value="aωb">
<p><input type="file" name="file1">
<p><input type="file" name="file2">
<p><input type="file" name="file3">
<p><button type="submit">Submit</button>
</form>
</body>
</html>
Vamos definir o valor de texto padrão para aωb
, o que significa aωb
porque ω
é U+03C9
, que são os bytes 61 CF 89 62
em UTF-8.
Criar ficheiros para enviar:
echo 'Content of a.txt.' > a.txt
echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html
# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary
Execute o nosso pequeno servidor echo:
while true; do printf '' | nc -l 8000 localhost; done
Abra o HTML no seu navegador, selecione os arquivos e clique em Enviar e verifique o terminal.
nc
imprime o pedido recebido.
Testado em: Ubuntu 14.04.3, nc
BSD 1.105, Firefox 40.
Multipart / form-data
Firefox enviado:
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"
text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"
aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream
aωb
-----------------------------735323031399963166993862150--
Para o ficheiro binário e o campo de texto, os bytes 61 CF 89 62
(aωb
em UTF-8) são enviados literalmente. Você poderia verificar isso com nc -l localhost 8000 | hd
, que diz que os bytes:
61 CF 89 62
Foram enviados (61
= = ' A ' e {[28] }= "b").
Portanto, é claro que:
-
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
define o tipo de conteúdo comomultipart/form-data
e diz que os campos são separados pela sequência indicadaboundary
.Mas note que:
boundary=---------------------------735323031399963166993862150
Tem menos dois dadhes
--
do que a barreira real-----------------------------735323031399963166993862150
Isto é porque o padrão requer que o limite comece com dois traços
--
. Os outros traços parecem ser a forma como o Firefox escolheu implementar o limite arbitrário. RFC 7578 claramente menciona que esses dois traços principais--
são necessários:4.1. Parâmetro "limite" do multipart/form-data
Tal como acontece com outros tipos de multipartas, as partes são delimitadas com um delimitador de limites, construído com CRLF,"--", e o valor de o parâmetro "limite".
-
Cada campo recebe alguns sub-cabeçalhos antes dos seus dados:
Content-Disposition: form-data;
, O camponame
, ofilename
, seguido pelos dados.O servidor lê os dados até a próxima linha de fronteira. O navegador deve escolher um limite que não aparecerá em nenhum dos Campos, então é por isso que o limite pode variar entre solicitações.
Porque temos o limite único, nenhuma codificação dos dados é necessária: dados binários são enviados como está.
TODO: Qual é o tamanho ideal do limite (
log(N)
eu aposto), e o nome / Tempo de execução do algoritmo que o encontra? Perguntado em: https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences -
Content-Type
é determinado automaticamente pelo navegador.Como é determinado exatamente foi perguntado em: como é que o tipo mime de um ficheiro carregado é determinado pelo navegador?
Application / x-www-form-urlencoded
Agora muda o enctype
para application/x-www-form-urlencoded
, recarrega o navegador, e reenviar.
Firefox enviado:
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary
Claramente os dados do arquivo não foram enviados, apenas os nomes de base. Então isso não pode ser usado para arquivos.
Como para o campo de texto, vemos que o habitual caracteres imprimíveis, como a
e b
foram enviados em um byte, enquanto o não-imprimíveis, como 0xCF
e 0x89
assumiu 3 bytes cada: %CF%89
!
Comparação
Os uploads de ficheiros contêm frequentemente muitos caracteres não imprimíveis( por exemplo, imagens), enquanto os formulários de texto quase nunca faço.
Dos exemplos vimos que:
multipart/form-data
: adiciona alguns bytes de limite acima da mensagem, e deve passar algum tempo calculando-a, mas envia cada byte em um byte.application/x-www-form-urlencoded
: tem um único limite de byte por campo (&
), mas adiciona um linear fator de sobrecarga de 3x para cada caractere não imprimível.
Mas para caracteres de impressão encontrados em campos de texto, isso não importa e gera menos sobrecarga, então nós apenas usá-lo.
enctype='multipart/form-data
é um tipo de codificação que permite que os ficheiros sejam enviados através de um POST. Muito simplesmente, sem esta codificação os arquivos não podem ser enviados através de POST .
Se quiser permitir que um utilizador envie um ficheiro através de um formulário, deve usar este enctype.
Ao enviar um formulário, você diz ao seu navegador para enviar, através do protocolo HTTP, uma mensagem na rede, devidamente envolvida numa estrutura de mensagens de protocolo TCP/IP. Uma página HTML tem uma forma de enviar dados para o servidor: usando <form>
s.
Quando um formulário é enviado, um pedido HTTP é criado e enviado para o servidor, a mensagem conterá os nomes dos Campos no formulário e os valores preenchidos pelo Usuário. Esta transmissão pode acontecer com POST
ou GET
HTTP métodos.
-
POST
diz ao seu navegador para criar uma mensagem HTTP e colocar todo o conteúdo no corpo da mensagem (uma forma muito útil de fazer as coisas, mais segura e também flexível). -
GET
irá apresentar os dados do formulário no querystring . Ele tem algumas restrições sobre a representação de dados e comprimento.
A indicar como enviar o seu formulário para o servidor
O atributo enctype
só faz sentido quando se utiliza o método POST
. Quando especificado, ele instrui o navegador para enviar o formulário codificando seu conteúdo de uma forma específica. De MDN - Form enctype:
Quando o valor do atributo method é post, o enctype é o MIME tipo de conteúdo que é usado para enviar o formulário para o servidor.
-
application/x-www-form-urlencoded
: Este é o padrão. Quando o formulário é enviado, todos os nomes e valores são coletados e codificação de URL é realizada no texto final. -
multipart/form-data
: Os caracteres não estão codificados. Isto é importante quando o formulário tem um controlo de envio de ficheiros. Você quer enviar o binário do arquivo e isso garante que o bitstream não é alterado. -
text/plain
: Os espaços são convertidos, mas não é feita mais codificação.
Segurança
Ao apresentar formulários, podem surgir algumas preocupações de segurança, tal como indicado na secção 7 da RFC 7578: considerações de segurança dos dados do formulário Multipart:
Todos os programas de processamento de formulários devem tratar formulário-data fornecido pelo utilizador
com sensibilidade, pois muitas vezes contém confidencial ou pessoalmente
identificacao. Existe um uso generalizado do formulário "auto-preenchimento" funcionalidades nos navegadores da web; estas podem ser usadas para enganar os utilizadores para
sem saber, enviar informações confidenciais ao completar o contrário
tarefas inócuas. multipart / form-data não fornece quaisquer características
para verificar a integridade, garantir a confidencialidade, evitar o utilizador
confusão ou outra elementos de segurança; essas preocupações devem ser
endereçadas pelas aplicações de preenchimento de formulários e interpretação de dados.Os pedidos que recebem formulários e os processam devem ser cuidadosos. não fornecer dados ao local de tratamento do formulário requerente que não era para ser enviado.
É importante ao interpretar o nome do ficheiro do conteúdo -
Campo de disposição do cabeçalho para não sobrepor inadvertidamente os ficheiros no
ficheiro do destinatário espaco.
Isto diz-lhe respeito se for um programador e o seu servidor irá processar os formulários enviados pelos utilizadores que poderão acabar por conter informações sensíveis.
enctype='multipart/form-data'
significa que nenhum personagem será codificado. é por isso que este tipo é usado durante o upload de arquivos para o servidor.
Então multipart/form-data
é usado quando um formulário necessita de dados binários, como o conteúdo de um ficheiro, para ser carregado
Defina o atributo método para publicar porque o conteúdo do ficheiro não pode ser colocado dentro de um parâmetro URL usando um formulário.
Defina o valor do enctype para multipart / form-data porque os dados serão divididos em várias partes, uma para cada ficheiro mais uma para o texto do corpo do formulário que pode ser enviado com eles.
- enctype (ENCode TYPE) atributo especifica como os dados do formulário devem ser codificados ao enviá-lo para o servidor.
- multipart / form-data é um dos valores do atributo enctype, que é usado no elemento form que tem um ficheiro carregado. Multi-part significa que os dados do formulário se dividem em múltiplas partes e enviam para o servidor.
Normalmente isto é quando você tem um formulário de POST que precisa tomar um arquivo upload como dados... isto irá dizer ao servidor como irá codificar os dados transferidos, caso em que não será codificado porque irá apenas transferir e carregar os ficheiros para o servidor, como por exemplo ao carregar uma imagem ou um pdf
O atributo enctype especifica como os dados do formulário devem ser codificados ao enviá-lo para o servidor.
O atributo enctype só pode ser utilizado se method= "post".
Não há caracteres codificados. Este valor é necessário quando estiver a usar formulários que tenham um controlo de envio de ficheiros
De W3Schools