Why do I have to use Formdata to send files via Ajax?

Asked

Viewed 1,791 times

2

I created an HTML page with a form, and in it a imput file and another field hidden, all of them with the attribute name.

<form id="meuForm" action="..." method="POST">
  <input type="hidden" name="itemId" value="1" />
  <input type="file" name="arquivo" accept=".csv" required />
  <input type="submit" value="Enviar" />
</form>

When trying to receive values as parameters in my Action did not succeed with the file, only with the other field hidden. I then tried to get the file through the Request, but once again I did not succeed.

[HttpPost]
public ActionResult Upload(int itemId, HttpPostedFileBase arquivo)
{
   // Forma alternativa
   var arquivoTeste = Request.Files["arquivo"];
}

To submit the form I tried to use the Ajax.BeginForm, but after several attempts I gave up.

@using (Ajax.BeginForm("Upload", "MeuController", new AjaxOptions()
{
    HttpMethod = "POST",
    OnSuccess = "ExibeRetorno",
    OnBegin = "IniciaLoad",
    OnFailure = "alert('Deu pau!')",
    OnComplete = "FinalizaLoad();"
}))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

  <input type="hidden" name="itemId" value="1" />
  <input type="file" name="arquivo" accept=".csv" required />
  <input type="submit" value="Enviar" />

}

I put together the whole ajax via Javascript, but nothing worked.

<form id="meuForm">
  <input type="hidden" name="itemId" id="itemId" value="1" />
  <input type="file" name="arquivo" id="arquivo" accept=".csv" required />
  <input type="button" id="enviar" value="Enviar" />
</form>

<script>
   (function(){
       $("#enviar").click(function(){
           var _itemId = $("#itemId).val();
           var _arquivo = $("#arquivo").get(0).files[0];

           $.ajax({
              beforeSend: function () {
                  IniciaLoad();
              },
              complete: function () {
                  FinalizaLoad();
              },
              contentType: "application/json, charset=utf-8",
              dataType: "json",
              type: "POST",
              url: '@Url.Action("Upload", "MeuController"})',
              data: JSON.stringify({
                    itemId: _itemId,
                    arquivo: _arquivo
              }),
              success: function (data) {

              },
              fail: function () {

               },
               error: function () {

               }
          });


       });

   })();
</script>

After several searches I found as an alternative to use the Formdata, and succeeded!

In my ajax (last example given), I made the following changes:

var formData = new FormData();
formData.append("arquivo", _arquivo);
formData.append("itemId", _itemId);


$.ajax({
       ...
       contentType: false,
       processData: false,
       data: formData,
       ...
});

But I couldn’t find a detailed answer as to why I couldn’t send the file by the above methods, but only with FormData.

1 - Why the above methods did not work?

2 - What’s different about Formdata is what makes it work?

  • Put the code in your question, otherwise how will we know where the error is?

  • Edited question!

1 answer

3


I ended up researching more and found the reason.

There is an attribute in the form called enctype, it is defined as the form data must be encoded when sending it to the server.

By default enctype="application/x-www-form-urlencoded" if nothing is specified, and in this case it is not possible to send files to the server.

To solve this just specify the value of the attribute as multipart/form-data, because in this encoding format it is possible to send files to the server. And then you don’t need ajax, but just do everything normally with form Ubmit.

But if the upload is being done directly in javascript with ajax (it uses the same type of encoding as default), then just use the interface FormData referenced in the question.

Fonte1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.