¿Se rota API de historial en iOS? (La barra de location no se actualiza en pushState)

Presentando esto bajo las categorías No puedo creer que nadie se dio count de esto antes o de lo que debo faltar Algo:

Parece que si haces un simple window.history.pushState en iOS, la barra de location no se actualiza a less que sea en respuesta a un gesto de usuario. El estado mismo se empuja (como puede ver al presionar el button del button Atrás).

Este es el caso de testing más pequeño en el que podría llegar a recrear el problema:

http://thelink.is/history-api-ios-bug

En un browser de escritorio compatible con History API, debería ver la URL en la barra de location cambiar a / 0, / 1, etc., cada segundo. En iOS, probado con iPhone (con iOS 4.3) e iPad (con iOS 4.3.3), la barra de location no se actualiza, pero si pulsa el button Atrás, obtendrá la location anterior correcta (que será 404 en el caso de testing desde no hay una lógica de back-end para manejar esas URL).

¿Pensamientos? Soluciones alternativas ¿Un hombro para llorar y abrazar?

ACTUALIZACIÓN: este problema se solucionó en iOS 5.

    Entonces, la conclusión es que iOS ha agregado su propia security alnetworkingedor de la API de historial, lo que significa que no puede usar secuencias de commands para cambiar la url. Solo una acción de usuario puede permitir que la API de historial cambie la url, es decir, un clic, según el ejemplo de Aral.

    La solución consiste en utilizar un hash (también conocido como identificador de fragment) en la url.

    En lugar de history.pushState solo cambiaremos la location:

     var i = 0; var locationUpdateInterval = setInterval(function(){ window.location.hash = i; i++; }, 1000); 

    Para capturar el evento cuando algo cambie esa location en la aplicación iOS o si tienen un enlace permanente a una página / panel en particular en su aplicación:

     // named function on purpose for later function hashchange() { var pageId = location.hash.substr(1); // drop the # symbol // do something with pageId } window.onhashchange = hashchange; // onload - if there's a hash on the url, try to do something with it if (location.hash) hashchange(); 

    Es bastante pobre que no podamos usar pushState / popState en iOS, pero es la misma security que no ser capaz de activar el video de pantalla completa a less que el usuario inicie la acción, que es lo mismo que download contenido de audio o video en iOS. no puede escribirlo, el usuario debe iniciarlo (de alguna manera u otra).

    Al igual que una nota sobre Android: los problemas son bastante similares, por lo que este (debería) también funciona como una solución para Android.

    Si desea soporte de escritorio, la mayoría de los browseres admiten onhashchange pero, sí, usted adivinó, IE está faltando detrás, para que pueda polyfiler a ese chico malo (aunque requiere jQuery …): http://benalman.com/projects/jquery -hashchange-plugin /

    Espero que ayude.

    Funciona bien para mí al usar: https://github.com/browserstate/history.js – esto también corrige muchos otros errores del browser cruzado con el HTML5 History API.

    A partir de v1.7, aquí están los errores que resuelve:

    • History.js resuelve los siguientes errores del browser:
      • Navegadores HTML5
        • Chrome 8 a veces no contiene los datos de estado correctos al volver al estado inicial
        • Safari 5, Safari iOS 4 y Firefox 3 y 4 no disparan el evento onhashchange cuando la página se carga con un hash
        • Safari 5 y Safari iOS 4 no disparan el evento onpopstate cuando el hash ha cambiado a diferencia de los otros browseres
        • Safari 5 y Safari iOS 4 no vuelven al estado correcto una vez que un hash es reemplazado por un replaceState reemploop / llamada replaceState
        • Safari 5 y Safari iOS 4 a veces no pueden aplicar el cambio de estado en condiciones de ocupado / informe de error
        • Google Chrome 8,9,10 y Firefox 4 antes del RC siempre dispararán en un estado onpopstate una vez que la página haya cargado / modificado la recomendación
        • Safari iOS 4.0, 4.1, 4.2 tiene una HTML5 History API activa, aunque los botones de retroceso reales de los browseres no funcionan, por lo tanto, los tratamos como browseres HTML4
        • Ninguno de los browseres HTML5 utiliza realmente el argumento del title para las llamadas pushState y replaceState
      • Navegadores HTML4
        • Los browseres antiguos como MSIE 6,7 y Firefox 2 no tienen un evento onhashchange
        • MSIE 6 y 7 a veces no aplican un hash ni siquiera se lo orderaron (requiriendo una segunda llamada a la function de request)
        • Los browseres HTML4 que no son de Opera a veces no aplican el hash cuando el hash no está urlencoded
      • Todos los browseres
        • Los datos y títulos de estado no persisten una vez que se deja el sitio y luego se devuelve (incluye actualización de página)
        • Los títulos de estado nunca se aplican al document.title

    (Actualización: acabo de ver que Remy también respondió: lea su respuesta en profundidad, arriba).

    Remy proporcionó una solución para este problema en Twitter.

    Básicamente, si cambia la location. Hash, la dirección en la barra de location se actualiza. Sin embargo, esto crea una input separada en el historial (que no funciona para lo que bash lograr). La solución que estoy implementando es utilizar URL de hash-bang para iOS y regulares para otras plataforms hasta que se corrija el error de iOS. Definitivamente, esto no es ideal y espero que Mobile Safari en iOS comience a comportarse como Chrome, Firefox y Safari en el escritorio.

    Esto es lo que encontré:

    Cuando la location presionada contiene un símbolo hash, la barra de direcciones se actualizará. Entonces esto funcionará:

     window.history.pushState(data, title, 'a/new/url#'); 

    Pero el object window.location no se actualizará, por lo que debe save la url empujada en una variable y usarla en lugar de window.location si necesita la location pulsada.

    Probado en Safari para Android.

    Encontré un truco que funciona un poco. Resulta que si cambia el hash inmediatamente después de history.pushState, la barra de location se actualiza. Me gusta:

      window.history.pushState(data, title, 'a/new/url'); window.location.hash = 'new'; 

    cambia la barra de location a http://example.com/a/new/url#new . Lo que introduce otro problema porque el hash se convierte en su propia input de historial. Por lo tanto, deberá escuchar onHashChange de todos modos.

    Es un poco complicado, pero hay algunas personas que realmente, realmente odian las direcciones URL hashbang y son muy vocales al respecto. Entonces vale la pena.