.Net 4.0 не может определить некоторые браузеры на основе AppleWebKit

Мы видим, что некоторые браузеры Safari не могут перекрестно аутентифицировать наш веб-сайт после того, как мы переходим на .NET 4.0 с .NET 3.5.

После долгих исследований выяснилось, что проблема связана с тем, что ASP.NET правильно идентифицирует браузеры Safari. ASP.NET идентифицирует некоторые Safari (возможно, другие браузеры на основе WebKit) в версии Mozilla версии 0.0. браузеры, которые не поддерживают файлы cookie, фреймы, JavaScript и т.д. У .NET 3.5 нет проблем с идентификацией этих браузеров.

Мы упростили тестирование вплоть до простого обработчика HTTP (работающего на веб-сайте vanilla 4.0), который возвращает возможности браузера только для браузера.

Вот несколько User-агентов, которые не могут быть идентифицированы (они определены как Mozilla 0.0):

  • Mozilla/5.0+(Macintosh;+U;+Intel+Mac+OS+X+10_5_8;+en-us)+AppleWebKit/533.19.4+(KHTML,+like+Gecko)+Version/5.0.3+Safari/533.19.4
  • Mozilla/5.0+(Macintosh;+U;+Intel+Mac+OS+X+10_6_2;+en-us)+AppleWebKit/531.9+(KHTML,+like+Gecko)
  • Mozilla/5.0+(Macintosh;+U;+Intel+Mac+OS+X+10_6_7;+en-us)+AppleWebKit/533.20.25+(KHTML,+like+Gecko)+Version/5.0.4+Safari/533.20.27
  • Mozilla/5.0+(Macintosh;+U;+Intel+Mac+OS+X+10_6_6;+en-us)+AppleWebKit/533.18.1+(KHTML,+like+Gecko)

Код обработчика выглядит следующим образом:

<%@ WebHandler Language="C#" Class="PowershellTemporaryHandler" %>

using System;
using System.Web;
using System.Web.Security;

public class PowershellTemporaryHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {        
        HttpBrowserCapabilities hbc = context.Request.Browser;
        context.Response.Write("Type=" + hbc.Type + "<br>");
        context.Response.Write("Name=" + hbc.Browser + "<br>");
        context.Response.Write("Version=" + hbc.Version + "<br>");
        context.Response.Write("Major Version=" + hbc.MajorVersion + "<br>");
        context.Response.Write("Minor Version=" + hbc.MinorVersion + "<br>");
        context.Response.Write("Platform=" + hbc.Platform + "<br>");
        context.Response.Write("Is Beta=" + hbc.Beta + "<br>");
        context.Response.Write("Is Crawler=" + hbc.Crawler + "<br>");
        context.Response.Write("Is AOL=" + hbc.AOL + "<br>");
        context.Response.Write("Is Win16=" + hbc.Win16 + "<br>");
        context.Response.Write("Is Win32=" + hbc.Win32 + "<br>");
        context.Response.Write("Supports Tables=" + hbc.Tables + "<br>");
        context.Response.Write("Supports cookies=" + hbc.Cookies + "<br>");
        context.Response.Write("Supports VBScript=" + hbc.VBScript + "<br>");
        context.Response.Write("Supports Frames=" + hbc.Frames + "<br>");
        context.Response.Write("Supports JavaScript=" + hbc.EcmaScriptVersion.ToString() + "<br>");
        context.Response.Write("Supports Java Applets=" + hbc.JavaApplets + "<br>");
        context.Response.Write("Supports ActiveX Controls=" + hbc.ActiveXControls + "<br>");
        context.Response.Write("User Agent=" + context.Request.UserAgent + "<br>");
    }
}

Мы сбиты с толку в связи с отсутствием упоминания в Интернете об этой проблеме. Похоже, что нам нужно добавить настройки браузера либо в папку framework/config/browsers, либо в папку App_Browsers на уровне веб-сайта, но кажется странным, что нам нужно будет настроить определения браузера для веб-сайта .NET 4.0 для правильной работы.

Есть ли у кого-нибудь опыт в этой проблеме?

Ответы

Ответ 1

Я столкнулся с тем, что похоже на аналогичную проблему. Похоже, что некоторые пользовательские агенты Safari не распознаются должным образом и вместо этого сообщаются как Mozilla 0.0, но некоторые исследования показали мне, что этот отказ не совсем воспроизводимый. Если я использую свой Firefox UserAgent-Switcher для отправки того же самого агента пользователя, который ранее не был распознан, и взгляните на возможности браузера, он правильно сообщается как Safari. Прохождение через файлы журнала сервера (после добавления некоторой информации отладки) также, похоже, подтверждает это поведение. Тот же клиент с одним и тем же (Safari) пользовательским агентом иногда распознается правильно и иногда сообщается как Mozilla 0.0 - большую часть времени он некорректно распознается пару раз подряд, прежде чем он снова получит его... Это только похоже, влияет на пользовательские агенты Safari - если кому-то интересно, у меня довольно длинный список, последний из которых:

  • | Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1, как Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, например, Gecko) Версия /5.0.2 Mobile/8C148 Safari/6533.18.5 |

Есть ли у кого-нибудь больше информации по этой проблеме?


EDIT 2011-08-24

Кажется, что я нашел основную причину проблемы. Механизм разрешения UserAgent → BrowserCaps использует кеш для временного хранения сопоставлений. К сожалению, он использует (по умолчанию) первые 64 символа строки UserAgent в качестве ключа кэша, а THAT - только BS... Иногда появляется пользовательский агент, который выглядит как Safari, но на самом деле это не так, и что он не разрешен должным образом (Mozilla 0.0), но сопоставление по-прежнему сохраняется в кеше, что означает, что все строки UserAgent с тем же префиксом 64 символов теперь неправильно отображаются, пока эта запись кэша не истечет (скользящее окно с 1 минутой). Ключевая длина, используемая для кэширования, к счастью, может быть сконфигурирована с помощью

<browserCaps userAgentCacheKeyLength="..." />

в разделе конфигурации. Я увеличил длину ключа до 256, и с тех пор проблема исчезла. Теперь я попытаюсь выяснить, какая строка UserAgent отвечает за отравление кеша в первом месте - и я обновлю это сообщение, если найду что-нибудь.

Ответ 2

Я попробовал все ответы из этого потока, но для User Agent от IPhone 4S:

Mozilla/5.0 (iPhone, U, CPU iPhone OS 4_3, как Mac OS X, de-de) AppleWebKit/533.17.9 (KHTML, например, Gecko) Mobile/8F190

Все пошло не так. В конце концов я использовал свойство ClientTarget со значением "uplvel", чтобы заставить ASP.NET всегда включать новые функции браузера. Я поместил это в базовый класс, который наследует все страницы.

Смотрите: http://msdn.microsoft.com/en-us/library/system.web.ui.page.clienttarget.aspx

Ответ 3

Решение

Я помещаю элемент <browserCaps userAgentCacheKeyLength='256'> в <system.web>, и все работает, как показано ниже:

<configuration>
    <system.web>
        <browserCaps userAgentCacheKeyLength="256" />
    </system.web>
</configuration>

Подробное объяснение

Функция разрешения 'Возможности браузера. Механизм разрешения кеша ключа пользователя использует кеш для временного хранения сопоставлений.

По умолчанию он использует первые 64 символа строки UserAgent в качестве ключа кеша, однако при появлении пользовательского агента, который выглядит так, как будто он принадлежит Safari, но на самом деле он не исправляется должным образом т.е. Mozilla 0.0 '

Отображение сохраняется в кеше, что означает, что все строки UserAgent с тем же префиксом 64 символа теперь неправильно отображаются до истечения срока действия записи кэша, т.е. обычно 1 минута.

Длина ключа, используемая для кеширования, настраивается следующим образом:

Увеличьте длину ключа до 256, чтобы устранить проблему.

... У меня возникли проблемы с поиском правильного места в файле web.config, чтобы вставить выше.

Когда я вставил элемент <browserCaps userAgentCacheKeyLength="..." /> непосредственно под <configuration> в мой файл web.config, мое веб-приложение сразу же разбилось.

К счастью, это произошло в тестовой среде, а не в рабочей среде.

После поиска в Интернете я нашел старую страницу справки MSDN/ASP.NET(http://msdn.microsoft.com/en-us/library/sk9az15a%28v=vs.71%29.aspx), которая предположила, что <broswerCaps> element является дочерним элементом <system.web>.