|
| 1 | +# 4.1 Procesando las entradas de los formularios |
| 2 | + |
| 3 | +Antes de comenzar, vamos a echarle un vistazo a un formulario típico de usuario, guardado como `login.gtpl` en tu carpeta de proyecto. |
| 4 | +``` |
| 5 | + <html> |
| 6 | + <head> |
| 7 | + <title></title> |
| 8 | + </head> |
| 9 | + <body> |
| 10 | + <form action="/login" method="post"> |
| 11 | + Nombre de Usuario:<input type="text" name="username"> |
| 12 | + Contraseña:<input type="password" name="password"> |
| 13 | + <input type="submit" value="Ingresar"> |
| 14 | + </form> |
| 15 | + </body> |
| 16 | + </html> |
| 17 | +``` |
| 18 | +Este formulario va a ser enviado a `/login` en el servidor. Después que el usuario de click en el botón Ingresar, la información va a ser enviada al manejador `login` registrado en nuestro enrutador. Entonces necesitamos saber qué método se usa, el POST o el GET. |
| 19 | + |
| 20 | +Es fácil darnos cuenta usando el paquete `http`. Veamos como manejar los formularios en la página de Ingreso. |
| 21 | +``` |
| 22 | + package main |
| 23 | +
|
| 24 | + import ( |
| 25 | + "fmt" |
| 26 | + "html/template" |
| 27 | + "log" |
| 28 | + "net/http" |
| 29 | + "strings" |
| 30 | + ) |
| 31 | +
|
| 32 | + func sayhelloName(w http.ResponseWriter, r *http.Request) { |
| 33 | + r.ParseForm() // Análizar los parámetros URL enviados, entonces analizar el paquete para analizar el cuerpo del paquete, para peticiones POST. |
| 34 | + // precaución: Si no se llama al método ParseForm, la siguiente unformación no podra ser obtenida del Formulario |
| 35 | + fmt.Println(r.Form) // Imprime la información del lado del servidor |
| 36 | + fmt.Println("path", r.URL.Path) |
| 37 | + fmt.Println("scheme", r.URL.Scheme) |
| 38 | + fmt.Println(r.Form["url_long"]) |
| 39 | + for k, v := range r.Form { |
| 40 | + fmt.Println("key:", k) |
| 41 | + fmt.Println("val:", strings.Join(v, "")) |
| 42 | + } |
| 43 | + fmt.Fprintf(w, "Hello astaxie!") // Escrite la respuesta |
| 44 | + } |
| 45 | +
|
| 46 | + func login(w http.ResponseWriter, r *http.Request) { |
| 47 | + fmt.Println("method:", r.Method) //get request method |
| 48 | + if r.Method == "GET" { |
| 49 | + t, _ := template.ParseFiles("login.gtpl") |
| 50 | + t.Execute(w, nil) |
| 51 | + } else { |
| 52 | + r.ParseForm() |
| 53 | + // Parte lógica de la función login |
| 54 | + fmt.Println("username:", r.Form["username"]) |
| 55 | + fmt.Println("password:", r.Form["password"]) |
| 56 | + } |
| 57 | + } |
| 58 | +
|
| 59 | + func main() { |
| 60 | + http.HandleFunc("/", sayhelloName) // Definimos la regla del enrutador |
| 61 | + http.HandleFunc("/login", login) |
| 62 | + err := http.ListenAndServe(":9090", nil) // Definimos el puerto de escucha |
| 63 | + if err != nil { |
| 64 | + log.Fatal("ListenAndServe: ", err) |
| 65 | + } |
| 66 | + } |
| 67 | +``` |
| 68 | + |
| 69 | +Aquí usamos el método `r.Methoc` para obtener el tipo de petición, el cual retornará uno de los siguientes verbos: "GET", "POST", "PUT", etc. |
| 70 | + |
| 71 | +En la función `login`, usamos `r.Method` para verificar si es una petición a la página o una petición para procesar los datos. En otras palabras, verificamos si el usuario solo abró la página o está intentando ingresar. Únicamente mostramos la página cuando viene desde un método GET, y ejecuta la lógica cuando viene un método POST. |
| 72 | + |
| 73 | +Podrás ver la interfaz cuando visitas `http://127.0.0.1:9090/login` en tu navegador. |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | +Figure 4.1 Interfaz de ingreso de usuario |
| 78 | + |
| 79 | +El servidor no va a imprimir nada hasta que nosotros escribamos un usuario y contraseña, porque el manejador no analizará los datos hasta que llamemos `r.ParseForm()`. Agreguemos `r.ParseForm()` antes de `fmt.Println("username:", r.Form["username"])`, compilemos el programa e intentémolo de nuevo. Ahora puedes ve la información en la consola del servidor. |
| 80 | + |
| 81 | +`r.Form` contiene todos los argumentos de la petición, por ejemplo la cadena de consulta en la URL y la información en el POST y PUT. Si la información tiene conflictos, como parámetros que tienen el mismo nombre, el servidor almacenará la información en un segmento con múltiples valores. La documentación de Go dice que Go guardará la información de las peticiones GET y el POST en diferentes lugares. |
| 82 | + |
| 83 | +Trata de cambiar la URL de ingreso de `http://127.0.0.1:9090/login` a `http://127.0.0.1:9090/login?username=astaxie` en el archivo `login.gtpl`, prueba de nuevo, Y podrás ver el segmento en el lado del servidor. |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +Figure 4.2 Server prints request data |
| 88 | + |
| 89 | +El tipo de `request.Form` es `url.Value`. Y lo guarda en el formato `llave=valor`. |
| 90 | +``` |
| 91 | + v := url.Values{} |
| 92 | + v.Set("name", "Ava") |
| 93 | + v.Add("friend", "Jess") |
| 94 | + v.Add("friend", "Sarah") |
| 95 | + v.Add("friend", "Zoe") |
| 96 | + // v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe" |
| 97 | + fmt.Println(v.Get("name")) |
| 98 | + fmt.Println(v.Get("friend")) |
| 99 | + fmt.Println(v["friend"]) |
| 100 | +``` |
| 101 | +**Recomendaciones** Las peticiones tienen la habilidad de acceder información por medio del método `FormValue()`. Por ejemplo, puedes cambiar de `r.Form["username"]` a `r.FormValue("username")`, y Go llamará `r.ParseForm` automáticamente. Nota que se retornará el primer valor, si existen varias llaves con el mismo nombre y retornará una cadena vacía si no existe el argumento. |
| 102 | + |
| 103 | +## Links |
| 104 | + |
| 105 | +- [Indice](preface.md) |
| 106 | +- Sección anterior: [Formulario de entrada de los usuario](04.0.md) |
| 107 | +- Siguiente sección: [Verificando las entradas](04.2.md) |
0 commit comments