ATS:加载淘宝页面

问题描述

项目中需要在App中加载一个淘宝网页,现在的问题是在iOS9上WebView呈空白状。淘宝链接如下:http://lsh-cat.taobao.com

解决过程

显然该链接是http,需要设置ATS(App Transport Security),设置如下:

<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>taobao.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

运行结果就是WebView呈白屏状态, console中显示:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

搜索了下,该错误代码是ssl中定义的,源码中对该代码的注释是 "Bad Mac"。这时,开始怀疑淘宝网没有使用TLS1.2,虽然这种可能性很小。考虑到ATS中可以设置的相关属性不多了,于是大胆的添加:

<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>

运行后,还是同样的问题。

深入分析

分析了网页加载的顺序,原始链接http://lsh-cat.taobao.com 会重定向到 https://shop61974942.m.taobao.com/,该链接是https。于是考虑使用https的链接进行测试,结果还是白屏,console输出相同的错误代码。 到这里,有点卡壳了,花了好多时间仔细查看官方文档,搜索 -9802,还是一无所获。在折腾了几个小时后,终于意识到淘宝的页面上还有其他域名的请求。接着在Chrome上检查了下,这时发现有alicdn,尝试添加该域名,运行,终于iOS9上页面正常的显示了。完整de设置如下:

<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>taobao.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
        <key>alicdn.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

总结

这类问题在解决时,不能局限在ATS设置本身,对请求源的分析也不能放过。在排查线索的时候,还是遵循确认已知问题到探索未知可能。当然Charles或者Wireshark绝对是不可或缺的利刃!!

参考:

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33