在3G网络下,iPad / iPhone浏览网站时出现JavaScript错误,但在WiFi下却没有。

24

在iPad使用3G连接http://www.manage-us.com会导致JavaScript错误,如果开启了开发者控制台,则可以看到该错误。而在同一iPad下使用WiFi连接访问相同页面时则不显示任何错误。[现在该错误已经被修复!]

为什么会出现这种情况呢?

我尝试在Mac上的Safari和iPad模拟器上模拟低带宽,但并未重现该问题。

目前我怀疑这是由于我在英国使用的移动运营商O2通过代理缓存(如降低图像文件质量)修改了某些内容导致的问题。如果您能确认当通过其他移动运营商的iPad或iPhone使用3G连接时没有出现此问题,那将有所帮助。


iPad是否会根据连接类型更改用户代理字符串?也许服务器会相应地提供不同的页面? - PaulJWilliams
"Javascript错误" - 你能详细说明一下吗? - Ana Betts
当前错误为:“ReferenceError: 找不到变量:liftAjax”。我之前在页面上放置了Google Analytics代码,并且在包含的ga.js代码中出现了与未终止注释相关的不同JavaScript错误。(但仅在通过3G连接时出现) - sroebuck
现在又回到了在 ga.js 代码中显示屏幕错误的状态。 - sroebuck
1
只是为了明确 - 网站不再显示错误,因为我应用了下面的修复方法。还有一个独立的相同问题案例也很有趣:http://oh7lzb.blogspot.com/2010/07/street-view-ipadiphone-beta-test.html - sroebuck
2个回答

34
我进一步调查发现,问题在于英国移动运营商O2(苹果的最初专属iPhone运营商)在将网页内容发送到iPhone和iPad之前修改了它。可能是在将其发送到任何运行移动浏览器的设备之前。
他们随机地将一些CSS和JavaScript内联到网页的主要源文件中。这可能会由于其算法错误或从源文件中剥离语法错误而导致错误,在其他情况下本来是无害的。
这些修改还会剥夺版权Javascript库和css库的版权信息,并对交付优化造成破坏。
例如,想象一下,如果用户访问您网站上链接到jQuery库的一系列页面。 O2不让您的移动浏览器本地缓存库,而是在每个页面上都内联该库,迫使您的手机为每个页面加载整个库。
我已经在这里写了一篇关于这个问题的博客,希望能引起更多关注:http://stuartroebuck.blogspot.com/2010/07/mobile-proxy-cache-content-modification.html 我的解决方法是使用document.write()在加载时插入JavaScript库的依赖项,以防止O2将它们内联。这似乎运作良好。例如:
<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>

请注意,如往常一样,如果页面作为 XHTML 提供,则 document.write 将不起作用。


1
非常好的发现。我已经注意到O2在通过3G提供网站时会进行压缩(当我在iPhone上使用共享网络时也会发生这种情况),但我没有意识到它们有时会导致JavaScript错误。我已经联系了他们,希望他们能在某个时候解决这个问题。 - Paul D. Waite
1
@Paul - O2有回复你关于这个问题吗?我在使用jQuery制作的网站上遇到了同样的问题,它会导致网站崩溃。他们有给你任何反馈吗?可能他们忽略了你... - Piotr Kula
1
@ppumkin:你看到sroebuck在这个问题上的博客文章了吗?这里有一个很好的总结:http://stuartroebuck.blogspot.com/2010/07/mobile-proxy-cache-content-modification.html - Paul D. Waite
4
@ppumkin提供了一个解决方法,而这里提供了一个解决方法:http://stuartroebuck.blogspot.com/2010/08/official-way-to-bypassing-data.html。 - Paul D. Waite
2
@PaulD.Waite 感谢您的回复。他们仍在进行,已经5年了。 - calumbrodie
显示剩余4条评论

1
对于任何需要ASP.NET解决方案的人,使用URL Rewrite Module 2.0 http://learn.iis.net/page.aspx/665/url-rewrite-module-20-configuration-reference,按照http://stuartroebuck.blogspot.com/2010/08/official-way-to-bypassing-data.html设置缓存控制头以处理JavaScript文件。
<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>

或者可以使用 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");
    }
}

<configuration>
   <system.web>
      <httpModules>
         <add name="AddHeaderModule" type="your.namespace.AddHeaderModule" />
      </httpModules>
   </system.web>
</configuration>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接