Android中Retrofit请求Azure网页仅返回部分内容的问题排查
为什么Retrofit请求Azure网页只返回部分内容?怎么获取完整渲染后的页面?
其实你遇到的不是Retrofit解析深度的问题——你拿到的已经是服务器返回的全部静态HTML内容,之所以看起来不完整,是因为这个页面是一个单页应用(SPA),那些<sidebar>、<pagecontent>这类自定义标签的内容,是通过页面底部的JS代码(比如System.import("app"))在浏览器端动态渲染出来的。
Retrofit作为纯HTTP客户端,只会发送请求、接收服务器直接返回的静态响应,它不会执行页面里的JavaScript,自然也看不到JS渲染后的动态内容。
解决思路分两种:
1. 优先调用API接口(推荐)
绝大多数SPA都会通过后端API来获取页面需要的数据,再用JS渲染到页面上。你可以打开浏览器的开发者工具(Network面板),查看页面加载过程中发起的XHR/Fetch请求,找到那些获取实际内容的API接口,然后直接用Retrofit请求这些接口,拿到结构化的数据(比如JSON),这样比获取HTML再解析要高效得多,也更符合服务端的设计意图。
2. 用WebView获取渲染后的完整HTML
如果必须要拿到最终渲染好的HTML内容,你可以用Android的WebView加载页面,等待JS执行完成后再获取页面源码:
// 注意要在主线程初始化WebView,或者处理好线程问题 WebView webView = new WebView(getApplicationContext()); WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); // 开启DOM存储,确保SPA能正常运行 webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 通过JS获取完整的页面HTML view.evaluateJavascript("document.documentElement.outerHTML;", html -> { // 这里的html就是渲染后的完整页面内容 // 注意返回的字符串会被转义,可能需要处理一下 System.out.println(html); }); } }); // 设置请求头(如果需要Basic认证的话) String login = "login"; String pass = "pass"; String authToken = Credentials.basic(login, pass); Map<String, String> headers = new HashMap<>(); headers.put("Authorization", authToken); webView.loadUrl("你的目标URL", headers);
注意事项:
- 需要在Manifest中添加
INTERNET权限 - WebView的内存占用较高,使用后要注意及时销毁,避免内存泄漏
- 如果页面有复杂的JS逻辑,可能需要等待更长时间,可以通过
WebChromeClient的onProgressChanged方法判断页面加载进度
补充说明:
- 你不用找Retrofit的"解析深度"设置,因为Retrofit根本不会解析HTML结构,它只是把服务器返回的响应体原封不动地转成字符串给你——你打印的内容就是服务器返回的全部内容。
- 没有触发内容过大的异常,说明响应体大小在OkHttp的默认限制内(默认10MB),这个问题和响应体大小无关。
内容的提问来源于stack exchange,提问作者Andrei Glushko
相关产品推荐
相关产品推荐

