puedo - El sitio web muestra un error de JavaScript en iPad/iPhone con 3G pero no con WiFi
operador no disponible iphone 6 (2)
Conectarse a http://www.manage-us.com en un iPad con 3G [utilizado para] provocar un error de JavaScript que se puede ver si la consola del desarrollador se ha habilitado. Si se accede a la misma página usando el mismo iPad con una conexión WiFi, no se muestra ningún error. [¡El error se ha ido ahora porque apliqué la solución a continuación!].
¿Por qué es esto?
Intenté simular un bajo ancho de banda (usando dummynet) en Safari en Mac y en el simulador de iPad en Mac. Esto no reproduce el problema.
Actualmente, sospecho que este es un problema que presenta mi operador de telefonía móvil en el Reino Unido (O2), que se sabe que modifica algunos contenidos a través de un caché de proxy, como la degradación de los archivos de imagen. Si puede confirmar que no tiene este problema al conectarse por 3G en un iPad o iPhone a través de otro operador de telefonía móvil, sería útil.
Investigué esto más a fondo y descubrí que el problema es que el operador de telefonía móvil del Reino Unido O2 (el operador de iPhone exclusivo original para Apple), modifica el contenido web antes de enviarlo a iPhones y iPads. Probablemente antes de enviarlo a cualquier dispositivo con un navegador móvil.
Integre de manera no determinista algunos de los CSS y JavaScript en los principales archivos fuente de las páginas web. Esto puede crear errores ya sea por errores en su algoritmo o por la consecuencia de eliminar el espacio en blanco de los archivos fuente con errores sintácticos en los archivos fuente que de otra manera serían benignos.
Estas modificaciones también eliminan los mensajes de derechos de autor de librerías javascript con derechos de autor y librerías CSS y causan estragos en las optimizaciones de entregas.
Por ejemplo, imagínese si un usuario está visitando una secuencia de páginas en su sitio que se vinculan a bibliotecas de jQuery. En lugar de permitir que su navegador móvil guarde en caché localmente la biblioteca, O2 alinea la biblioteca en cada página, forzando a su teléfono a cargar toda la biblioteca una y otra vez para cada página.
He escrito un blog sobre el tema aquí con la esperanza de llamar un poco más la atención sobre esto: http://stuartroebuck.blogspot.com/2010/07/mobile-proxy-cache-content-modification.html
Mi solución consiste en utilizar document.write()
para insertar las dependencias de la biblioteca de JavaScript en el momento de la carga y evitar que O2 las delimite. Esto parece funcionar bastante bien. p.ej:
<script type="text/javascript">
// <![CDATA[
// Using document.write to load JavaScript dependencies to bypass O2 network inlining of JavaScript.
function loadJS(file){document.write("<" + "script type=''text/javascript'' src=''" + file + "''></" + "script>")}
loadJS("/js/jquery-1.4.2.min.js");
loadJS("/js/myJSLibrary.js");
// ]]>
</script>
Tenga en cuenta que, como siempre, document.write
no funcionará si la página se sirve como XHTML.
Para cualquiera que necesite una solución para esto en ASP.NET, establece el encabezado Cache-Control según stuartroebuck.blogspot.com/2010/08/… para los archivos javascript que utilizan URL Rewrite Module 2.0 http://learn.iis.net/page.aspx/665/url-rewrite-module-20-configuration-reference .
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Compression header" preCondition="Match JS Files">
<match serverVariable="RESPONSE_Cache-Control" pattern="(.*)" />
<action type="Rewrite" value="no-transform" />
</rule>
<preConditions>
<preCondition name="Match JS Files">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="(javascript)$" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Alternativamente se puede hacer usando un HttpModule
public class AddHeaderModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.EndRequest += OnEndRequest;
}
void OnEndRequest(object sender, System.EventArgs e)
{
if(HttpContext.Current.Response.ContentType.Contains("javascript"))
HttpContext.Current.Response.Headers.AddHeader("Cache-Control", "no-transform");
}
}
y
<configuration>
<system.web>
<httpModules>
<add name="AddHeaderModule" type="your.namespace.AddHeaderModule" />
</httpModules>
</system.web>
</configuration>