HTTPDNS : 接入过程中需要注意哪些问题 ?

在集成HTTPDNS服务时,开发者需要了解下述场景的特殊性及可能涉及的定制需求:

  • 务必编写降级代码

    • 降级代码指的是HTTPDNS无法获取期望结果时的处理代码。

    • 如何降级?走传统的DNS解析流程获取域名对应的 IP,可以参考HTTPDNS的demo代码。

  • 终端配置代理情况下的处理机制,请参考单域名解析接口关于代理场景下的处理建议,一个方案是降级处理,另一个方案是采用私有头进行双端配合处理。

  • 使用HTTPDNS服务时,由于多数场景下开发者需要替换URL中的域名信息为IP,导致传统网络库把IP信息作为Cookie对应的域名信息进行存储管理,进而造成一定的困扰。建议类似场景的Cookie管理由用户自己定制管理。

  • HTTPS场景、WebView场景、单服务器服务多域名的HTTPS场景下的HTTPDNS解决方案较通用场景下的解决方案更复杂一些,请参见Android端HTTPS(含SNI)业务场景"IP直连"方案说明iOS端HTTPS(含SNI)业务场景“IP直连”方案说明

  • 参考Android端HTTPDNS+Webview最佳实践实现时,需注意以下两点:

    • 请留意Android API < 21时系统库函数只能拦截到请求的url参数,其他参数(包括method、header、body等)都没法正常获取。Android API >= 21时,针对POST请求的body内容,WebResourceRequest接口中并没有提供相应的获取方式。

    • 在Webview场景下,当开发者使用HttpURLConnection进行网络请求时,网络库默认的处理机制会内部消化跳转请求,从而使Webview无法感知跳转行为的存在。即当域名A跳转到域名B后,其附带的其他资源请求如”/render/something.css”依然会被Webview定向到”A/render/something.css”而非”B/render/something.css”,从而导致访问异常。

      解决方案为:配置HttpURLConnection不自动处理跳转请求,并在shouldInterceptRequest中判断请求响应码,如为跳转响应码则退出拦截,降级为原生访问模式,参考示例:

      HttpURLConnection.setFollowRedirects(false);
      ...
      public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
          ...
          int respCode = conn.getResponseCode();
          if (respCode >= 300 && respCode < 400) {
              // redirect
              return null;
          } else if (respCode >= 200 && respCode < 300) {
              // normal processing
              ...
          }
      }

上述问题的更详细方案请参见Google论坛中关于Webview的讨论。

  • iOS 使用 NSURLProtocol 拦截 NSURLSession 发起的 POST 请求时,HTTPBody 无法正常获取(系统bug),解决方案有两个:

    1. 使用NSURLConnection发POST请求。

    2. 先将HTTPBody放入HTTP Header field中,然后在NSURLProtocol中再取出来,具体可参考相关文章中的介绍。