Pasar al contenido principal
Alexys Lozada
José Luján
Manuel Rodriguez
José Luján
Luis Avilés
Álvaro Felipe
José Luján
Beto Quiroga
Jonathan MirCha
Jonathan MirCha
Álvaro Felipe
Alexys Lozada, Álvaro Felipe, Jonathan MirCha
Beto Quiroga
Alexys Lozada
Alexys Lozada
José Luján
Álvaro Felipe
Álvaro Felipe
Jonathan MirCha
Jonathan MirCha
Alexys Lozada, José Luján
Alexys Lozada, José Luján
Alexys Lozada, José Luján
Camilo Adobe
Álvaro Felipe
José Luján
Jonathan MirCha
Álvaro Felipe
Álvaro Felipe
Beto Quiroga, Alexys Lozada
Álvaro Felipe
Juan Villalvazo
Luis Avilés
Jonathan MirCha
Jonathan MirCha
Jonathan MirCha

¿Cómo subir archivos al servidor con Go (golang) y Ajax?

¿Cómo subir archivos al servidor con Go (golang) y Ajax?

Subir archivos al servidor es una funcionalidad muy común que realizamos en muchas de las páginas web que construimos, puede ser para subir el avatar para el perfil de un usuario, para una galería de imágenes o la carátula de un artículo, etc. Pero ¿qué pasa si lo quieres hacer usando una tecnología como Ajax?, veamos una posible solución a este problema.

Primero mostraré la estructura de carpetas y archivos que usaremos en este ejercicio:

public\
    api.js
    app.js
    index.html
    style.css
controllers\
    file.go
files\

Abrimos el archivo index.html y escribimos el siguiente código HTML:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, 
    user-scalable=no, initial-scale=1.0, maximum-scale=1.0,
minimum-scale=1.0">
    <link rel="stylesheet" 
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="styles.css">
    <title>File upload using Ajax</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data" class="uploadForm">
        <input class="uploadForm__input" type="file" name="file" id="inputFile" accept="image/*">
        <label class="uploadForm__label" for="inputFile">
            <i class="fa fa-upload uploadForm__icon"></i> Select a file
        </label>
    </form>
    <div class="notification" id="alert"></div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="api.js"></script>
    <script src="app.js"></script>
</body>
</html>

Ahora vamos añadir algunos estilos básicos a nuestro formulario, en el archivo styles.css:

body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100vh;    
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}

body,
.uploadForm,
.uploadForm__label {
    display: flex;
    align-items: center;
    justify-content: center;
}

.uploadForm {
    width: 600px;
    max-width: 600px;
    height: 300px;
    flex-direction: column;    
    border: 2px dashed gray;
    font-family: inherit;
}

.uploadForm__input {
    display: none;
}

.uploadForm__label {
    border: 1px solid gray;
    padding: .5em 2em;
    color: deepskyblue;
    transition: transform .4s;
    flex-direction: column;
}

.uploadForm__label:hover {
    cursor: pointer;
    transform: scale(1.01);
    box-shadow: grey 2px 2px 10px;
}

.uploadForm__icon {
    font-size: 1.8em;
}

.notification {    
    display: none;    
}

.success,
.error {
    right: 30px;
    z-index: 10;
    width: 300px;
    bottom: 40px;
    padding: 1em;
    height: auto;
    text-align: center;
    display: block;
    position: fixed;
    font-family: inherit;
    animation: alert .8s forwards;
}

.notification.success {
    background: #D9EDF7;
    color: #31709C;
}

.notification.error {
    background: #F2DEDE;
    color: #B24842;
}

@keyframes alert {
    0% {
        opacity: 0;
        bottom: -40px;
    }

    100% {
        opacity: 1;
        bottom: 40px;
    }
}

Dentro del archivo app.js pondremos el código js necesario para mandar nuestro archivo;

(function (d, axios) {
    "use strict";
    var inputFile = d.querySelector("#inputFile");
    var divNotification = d.querySelector("#alert");

    inputFile.addEventListener("change", addFile);

    function addFile(e) {
        var file = e.target.files[0];
        if(!file){
            return;
        }
        upload(file);
    }

    function upload(file) {
        var formData = new FormData();
        formData.append("file", file);
        post("/upload", formData)
            .then(onResponse)
            .catch(onResponse);
    }

    function onResponse(response) {
        var className = (response.status !== 400) ? "success" : "error";
        divNotification.innerHTML = response.data;
        divNotification.classList.add(className);
        setTimeout(function() {
            divNotification.classList.remove(className);
        }, 3000);
    }
})(document, axios);

Finalmente dentro del archivo api.js haremos uso de la librería axios para mandar nuestra petición Ajax al servidor:

"use strict";

function post(url, data) {
    return axios.post(url, data)
        .then(function (response) {
            return response;
        }).catch(function (error) {
            return error.response;
        });
}

Bién, para manejar la petición del lado del servidor usaremos el archivo file.go que está dentro de la carpeta controllers escribiendo el siguiente código:

package controllers

import (
    "fmt"
    "io/ioutil"
    "mime/multipart"
    "net/http"
)

// UploadFile sube el archivo al servidor
func UploadFile(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Redirect(w, r, "/", http.StatusSeeOther)
        return
    }

    file, handle, err := r.FormFile("file")
    if err != nil {
        fmt.Fprintf(w, "%v", err)
        return
    }
    defer file.Close()

    mimeType := handle.Header.Get("Content-Type")
    switch mimeType {
    case "image/jpeg":
        saveFile(w, file, handle)
    case "image/png":
        saveFile(w, file, handle)
    default:
        jsonResponse(w, http.StatusBadRequest, "The format file is not valid.")
    }
}

func saveFile(w http.ResponseWriter, file multipart.File, handle *multipart.FileHeader) {
    data, err := ioutil.ReadAll(file)
    if err != nil {
        fmt.Fprintf(w, "%v", err)
        return
    }

    err = ioutil.WriteFile("./files/"+handle.Filename, data, 0666)
    if err != nil {
        fmt.Fprintf(w, "%v", err)
        return
    }
    jsonResponse(w, http.StatusCreated, "File uploaded successfully!.")
}

func jsonResponse(w http.ResponseWriter, code int, message string) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(code)
    fmt.Fprint(w, message)
}

Como último paso dentro del archivo main.go haremos uso de nuestro controlador de la siguiente forma:
 

package main

import (
    "log"
    "net/http"

     // Nota esta es mi GOPATH cambiala de acuerdo a la tuya.
    "bitbucket.org/gustavocd/upload-img/controllers"
)

func main() {
    http.Handle("/", http.FileServer(http.Dir("./public")))
    http.HandleFunc("/upload", controllers.UploadFile)
    log.Println("Running")
    http.ListenAndServe(":8080", nil)
}

Ahora solo tienes que ejecutar el siguiente comando en la terminal y después visitar http://localhost:8080 en tu navegador para empezar a subir tus archivos:

go run main.go

Eso es todo por este artículo, espero les sea de utilidad, gracias por leerlo y nos vemos en una próxima ocasión.

Suscríbete al blog de EDteam

Ingresa tu correo electrónico para recibir nuestro boletín semanal