IOS6 y la caché de llamadas POST

Aún recuerdo cuando todavía daba soporte a ie6 y tenía que pelearme con su incorrecta interpretación del modelo de cajas, siempre maldecía la forma que tenía microsoft de pasarse por el forro los estándares y soñaba con el día en que la compentecia cogiera empuje y tuviesen que ir por el mismo camino que los demás para hacer de la web un sitio mejor.

Apple a sacado la última versión de su sistema operativo para móviles, ios6, y han hecho lo que pensaba que era coto privado de microsoft, interpretar los estándares a su manera y de paso fastidiarnos a todos esta semana, han decido cachear por defecto las llamadas POST.

Si después de leer lo anterior no te has llevado las manos a la cabeza puede ser por dos motivos:

  • Eres un fanboy de apple
  • No sabes lo que esto implica

Puedes leer más sobre el tema aqui y aqui.

Se pueden buscar soluciones, como veremos más adelante, pero he de reconocer lo que me molesta arreglar algo que no está roto, que indudablemente es un bug, sin aparentemente ninguna justificacion, ¿Apple estará demasiado endiosada?

En la aplicación en la que estoy actualmente trabajando hacemos un uso intensivo de javascript y ajax, algunos clientes que han actualizado a ios6 sus dispositivos han empezado a experimentar algunos problemas que no ocurrían en la versión anterior, la 5.1.1, tras comprobar que se debía a este bug he intentado buscar algunas soluciones.

  • Añadir un parametro basado en el timestamp para intentar evitar el cacheo.
  • Devolver la cabecera Cache-control no-cache en las llamadas para indicarle al safari, que no cachee los resultados.

El primero me parece un poco fea y la segunda puede ser un poco complicada de implementar a nivel de aplicación dependiendo de tu escenario.

Como usamos nginx como balanceador de carga contra nodejs hemos usado la directiva add_header para añadir esta cabecera de forma tranparente a la aplicación y además solo a las llamadas POST

...
server {
  listen 443 ssl;
  ...

  location / {
    root /var/www/app;
    try_files /public$uri @proxy;
  }

  location @proxy {
    # try fix ios6 bug
    if ($request_method = POST) {
      add_header Cache-Control "no-cache";
    }
    proxy_set_header X-Real-IP $remote_addr;
    ...

En los links que mencioné antes encontrareis algunas soluciones para apache que es la misma que he implementado pero usando nginx.

Apple por favor no te conviertas en la nueva microsoft.