Подтвердить что ты не робот

Веб-сайт демонстрирует ошибку JavaScript на iPad/iPhone под 3G, но не под WiFi

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

Почему это?

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

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

4b9b3361

Ответ 1

Я исследовал это дальше и обнаружил, что проблема в том, что британский оператор мобильной связи 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.

Ответ 2

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

Альтернативно может быть сделано с использованием 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>