Веб-сайт показывает ошибку JavaScript на iPad / iPhone под 3G, но не под WiFi - PullRequest
24 голосов
/ 19 июля 2010

Подключение к http://www.manage -us.com на iPad под 3G [используется] приводит к ошибке JavaScript, которую можно увидеть, если была включена консоль разработчика.Если доступ к той же странице осуществляется через тот же iPad с подключением WiFi, ошибка не отображается.[Ошибка теперь исчезла, потому что я применил исправление ниже!].

Почему это?

Я пытался симулировать низкую пропускную способность (используя dummynet) в Safari на Mac и на iPadсимулятор на Mac.Это не воспроизводит проблему.

В настоящее время я подозреваю, что это проблема, представленная моим мобильным оператором в Великобритании (O2), который, как известно, изменяет некоторый контент через кэш-прокси, такой как понижение качества файлов изображений.Если вы можете подтвердить, что у вас нет этой проблемы при подключении через 3G на iPad или iPhone через другого оператора мобильной связи, это будет полезно.

Ответы [ 2 ]

34 голосов
/ 20 июля 2010

Я исследовал это дальше и обнаружил, что проблема в том, что мобильный оператор Великобритании O2 (оригинальный эксклюзивный оператор iPhone для Apple) изменяет веб-контент перед отправкой его на 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>

Обратите внимание, что, как всегда, document.write не будет работать, если страница будет отображаться как XHTML.

1 голос
/ 09 февраля 2012

Для тех, кому нужно решение этой проблемы в ASP.NET, это устанавливает заголовок Cache-Control в соответствии с http://stuartroebuck.blogspot.com/2010/08/official-way-to-bypassing-data.html для файлов JavaScript с использованием модуля перезаписи URL 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>

В качестве альтернативы можно использовать 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>
...