iOS 8 / Safari 8与ASP.NET AJAX扩展不兼容

33
我们的网站在 iOS 8 发布后突然停止了工作。 在 ASP.NET UpdatePanel 中的每次 post-back 都会导致一个空白页面。 如果在 Safari 8(在 Mac 上)中将用户代理设置为“Chrome”,则仍然可以正常工作。
我已经找到了一些未能加载的“ScriptResource.axd”和“WebResource.axd”文件。 还有一个错误提示“Sys.WebForms”未定义(可能是由于缺少脚本文件导致的)。
我们正在使用 ASP.NET 2.0 和 AJAX-Extensions 1.0(我知道,相当过时。但以前可行,或者直到现在可以修复)。

1
真希望我昨天就能找到这篇文章 - 我刚想写同样的东西。 - Yellowfog
3个回答

57

请注意,此解决方案仅适用于 .NET 版本小于 4.0 的情况

以下是解决方法...

可工作 UA:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36

不可工作 UA:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10

问题在于 AppleWebKit/600 的主要版本变化。 ASP.NET AJAX 无法正确识别新的 Safari 8 浏览器(在 iOS 8 中也是如此)。 它认为不支持部分呈现。 我在 “PageRequestManager.cs” 中找到了以下行:

bool supportsPartialRendering = (browser.W3CDomVersion >= MinimumW3CDomVersion) && (browser.EcmaScriptVersion >= MinimumEcmaScriptVersion) && browser.SupportsCallback;

MinimumEcmaScriptVersion/MinimumW3CDomVersion都是1。Request.Browser给了我以下结果:

W3CDomVersion = 1.0
EcmaScriptVersion = 1.0
SupportsCallback = false
即使 "EcmaScriptVersion" 的值很奇怪,问题主要是由于 SupportsCallback 为 false 导致的。 这个 bug 存在于随 ASP.NET 一起发布的 "mozilla.browser" 文件中(位于 "C:\Windows\Microsoft.NET" 中的某个地方):
<browser id="Safari60" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="60" />
</identification>
<capture>
</capture>
<capabilities>
  <capability name="ecmascriptversion"       value="1.0" />
  </capabilities>
</browser>

<browser id="Safari85" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="85" />
  </identification>
  <capture>
  </capture>
  <capabilities>
    <capability name="ecmascriptversion"       value="1.4" />
  </capabilities>
</browser>

<browser id="Safari1Plus" parentID="Safari">
  <identification>
    <capability name="appleWebTechnologyVersion" match="\d\d\d" />
  </identification>
  <capture>
  </capture>
  <capabilities>
    <capability name="ecmascriptversion"       value="1.4" />
    <capability name="w3cdomversion"           value="1.0" />
    <capability name="supportsCallback"        value="true" />
  </capabilities>
</browser>

所有新于“Safari 85”的内容都应该被最后一个定义所捕获。但是由于混乱的正则表达式,"Safari 600" 被错误地检测为 "Safari60":

<capability name="appleWebTechnologyVersion" match="60" />

应该已经是

<capability name="appleWebTechnologyVersion" match="60$" />

我通过添加一个名为"App_Browsers\safari.browser"的自定义文件来解决了这个问题,其内容如下:

<browsers>
  <browser id="Safari60_bugfix" parentID="Safari60">
    <identification>
      <capability name="appleWebTechnologyVersion" match="^\d{3,}$" />  <!-- At least 3 digits -->
    </identification>

    <capabilities>
      <!-- Same as in "Safari1Plus" -->
      <capability name="ecmascriptversion" value="1.4" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="supportsCallback" value="true" />
     </capabilities>
  </browser>

  <browser id="Safari85_bugfix" parentID="Safari85">
    <identification>
      <capability name="appleWebTechnologyVersion" match="^\d{3,}$" />  <!-- At least 3 digits -->
    </identification>

    <capabilities>
      <!-- Same as in "Safari1Plus" -->
      <capability name="ecmascriptversion" value="1.4" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="supportsCallback" value="true" />
    </capabilities>
  </browser>
</browsers>

1
值得注意的是,在http://forums.asp.net/t/955969.aspx?Mastering+Browser+Definition+Files中报告的错误可能会阻止您的其他浏览器文件被拾取。 - Yellowfog
7
为了让人们不必阅读上面的链接,你需要在/App_Browsers文件夹中“触碰”(即编辑并保存)其他任何文件,以触发新的.browser文件被选中。请注意保留原意,并使翻译通俗易懂。 - user2444499
2
@stoj:我打错字了,这是正确的评论,谢谢!我还建议,如果您决定更改原始的mozilla.browser文件,请执行命令:\WINDOWS\Microsoft.NET\Framework\aspnet_regbrowsers.exe -i,它会重新编译规则。此解决方案中解释的规则适用于框架版本2.0。这是链接http://msdn.microsoft.com/en-US/library/ms229858(v=vs.80).aspx - Matteo Conta
@Jules:当我实施上述解决方案时,出现了“找不到ID为'Safari60'的浏览器或网关元素”的错误。你有什么想法,我可能做错了什么吗? - Ajit Goel
@Tobias81 https://dev59.com/jY7ea4cB1Zd3GeqPCII8 - Habib Adıbelli
显示剩余11条评论

3
问题仅在使用自定义浏览器功能时出现,即一个人拥有.app_browsers文件夹中的.browser文件。原因是:微软曾经发布一个修复程序(请参阅http://support.microsoft.com/kb/2836946以获取更多详细信息),其中解决了一些浏览器兼容性问题,包括我们在此处看到的问题; 但是,由于兼容性问题,当使用自定义浏览器功能时,该修复程序将不会生效。因此,对于任何使用自定义浏览器功能文件的人来说,不幸的是,解决所报告的问题的最佳方法是采用Tobias81提供的解决方法。

2

我按照@Tobias81提到的解决方案进行了实现,但是出现了“无法找到ID为'Safari60'的浏览器或网关元素”的错误。因此,我通过更改应用程序Web.config中的元素来匹配更新的版本并分配正确的功能,从而解决了这个问题。

<configuration>   
  <system.web>     
    <browserCaps>       
      <filter>
        <case match="AppleWebKit/600">EcmaScriptVersion = 1.5           
          supportsCallback = true         
        </case>       
      </filter>     
    </browserCaps>   
  </system.web>
</configuration>

在我的asp.net应用程序中,Apple IOS8和MAC Safari的验证未能正常工作。上述帮助对我非常有用。现在它也支持Apple IOS8和MAC Safari。 - Shoeb
这在旧版本的IOS(如8)中运行良好,但在最新的IOS 9.1上无法工作。请帮忙... - Shoeb
问题已通过将匹配值替换为“AppleWebKit/601”解决。在最新的IOS 9.1上正常工作。 - Shoeb

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