Web site exhibits JavaScript error on iPad / iPhone under 3G but not under WiFi

最后都变了- 提交于 2019-11-27 08:16:55

I've investigated this further and discovered that the problem is that the UK mobile operator O2 (the original exclusive iPhone operator for Apple), modifies web content before sending it to iPhones and iPads. Probably before sending it to any device running a mobile browser.

They non-deterministically inline some of the CSS and JavaScript into the main source files of the web pages. This can create errors either because of mistakes in their algorithm or the consequence of stripping white space from source files with syntactic mistakes in the source files which were otherwise benign.

These modifications also strip copyright messages from copyrighted javascript libraries and css libraries and play havoc with delivery optimisations.

For example, imagine if a user is visiting a sequence of pages on your site which all link to jQuery libraries. Instead of letting your mobile browser locally cache the library, O2 inline the library on every page, forcing your phone to load the entire library over and over again for every page.

I've written a blog about the issue here in the hope if drawing a bit more attention to this: http://stuartroebuck.blogspot.com/2010/07/mobile-proxy-cache-content-modification.html

My workaround is to use document.write() to insert the JavaScript library dependencies at load time and prevent O2 from inlining them. This seems to work quite well. e.g.:

<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>

Note that, as ever, document.write will not work if the page is served as XHTML.

For anyone needing a solution to this in ASP.NET, this sets the Cache-Control header as per http://stuartroebuck.blogspot.com/2010/08/official-way-to-bypassing-data.html for javascript files using 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>

Alternatively can be done using a 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");
    }
}

and

<configuration>
   <system.web>
      <httpModules>
         <add name="AddHeaderModule" type="your.namespace.AddHeaderModule" />
      </httpModules>
   </system.web>
</configuration>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!