Download file via Ajax

Asked

Viewed 3,686 times

3

In my Asp.Net MVC 4 project, I have a View with a button and the following script:

<input type="button" value="Teste" id="baixarArquivo" />

<script>

(function () {

    $("#baixarArquivo").off("click").on("click", function () {
        DownloadArquivo();
    });

    function DownloadArquivo() {
        $.ajax({
            beforeSend: function () {
                // Inicia Load
            },
            complete: function () {
                // Finaliza Load
            },
            contentType: 'application/json, charset=utf-8',
            dataType: 'json',
            type: 'POST',
            url: '@Url.Action("DownloadArquivo", "MeuController", new { area = "Administrador" })',
            // Parâmetros
            //data: JSON.stringify(
            //    {
            //        Param1: minhaVar,
            //    }),
            success: function (data) {
                if (data.success) {
                    // Baixar arquivo
                } else {
                    alert("Erro! " + data.title + " " + data.error);
                }
            },
            fail: function () {
                alert("Error 007");
            }
        });
    }
})();
</script>

In the Controller my Action is as follows:

    [HttpPost]
    public ActionResult DownloadArquivo()
    {
        try
        {
            byte[] fileBytes = null;

            using (MemoryStream ms = new MemoryStream())
            {
                using (TextWriter tw = new StreamWriter(ms))
                {
                    tw.WriteLine("Este é apenas um teste!");

                    tw.Flush();
                    ms.Flush();

                    fileBytes = ms.ToArray();
                }
            }

            return Json(new
            {
                success = true,
                content = fileBytes,
                fileName = "meuArquivo",
                mimeType = System.Net.Mime.MediaTypeNames.Text.Plain
            }, JsonRequestBehavior.AllowGet);

        }
        catch (Exception ex)
        {
            return Json(new
            {
                success = false,
                error = ex.Message,
                title = "Download"
            }, JsonRequestBehavior.AllowGet);
        }

    }

How to download the file if everything goes well?

  • In the Success of the call from ajax, make a console.log(data);, see if you print something.

2 answers

3

You can use a plugin JavaScript called Download.js, but it has no compatibility with previous versions of Internet Explorer, only from 9.

Another solution is you open one iframe to download, at the end of the accounts is transparent to the user.

<input type="button" value="Teste" id="baixarArquivo" />
<iframe id="meu-iframe" style="display:none"></iframe>

<script type="text/javascript">

    $("#baixarArquivo").click(function () {
        DownloadArquivo();
    });

    function DownloadArquivo() {
        $('#meu-iframe').attr('src', '@Url.Action("DownloadArquivo", "MeuController", new { area = "Administrador" })');
    }
</script>

I hope I helped the/

1

Jedaias, the MVC has a ViewResult own to archives, in case the FileResult

Below is a complete example with the Upload and the Download of the same file through AJAX.

Model

public class RequestModel
{
    public HttpPostedFileBase Arquivo { get; set; }
}

Controller

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new { });
    }


    [HttpPost]
    public FileResult SendFile(RequestModel model)
    {
        return File(model.Arquivo.InputStream, model.Arquivo.ContentType, model.Arquivo.FileName);
    }
}

View

<form id="formulario" method="POST" action="@Url.Content("~")Home/SendFile">
    <div>
        <label>
            Arquivo:
            <input id="Arquivo" name="Arquivo" type="file" />
        </label>
    </div>
    <div>
        <input id="enviar" type="submit" />
    </div>
</form>

Javascript

var formulario = document.getElementById("formulario");
formulario.addEventListener("submit", function (event) {
    event.preventDefault();

    var method = event.target.method;
    var action = event.target.action;
    var data = new FormData(event.target);

    var httpRequest = new XMLHttpRequest();
    httpRequest.open(method, action, true);
    httpRequest.responseType = "blob";
    httpRequest.addEventListener("readystatechange", function (event) {
        if (httpRequest.readyState == 4) {
            var blob = httpRequest.response;

            var url = URL.createObjectURL(blob);
            var link = document.createElement("a");
            var event = new Event("click");
            link.href = url;
            link.download = "<%nome do arquivo%>";
            link.dispatchEvent(event);
            URL.revokeObjectURL(url);
        }
    });

    httpRequest.send(data);
});

If you need to monitor upload/download progress, make use of the "Preview event"

httpRequest.addEventListener("progress", function (event) {
  if (event.lengthComputable) {
    var percent = event.loaded / event.total;
  }
});

The problem of downloading a file by AJAX, is that it is not possible to catch the name of the file by XMLHttpRequest.response, then you will set the file name directly on JavaScript.

Browser other questions tagged

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