# iOS WKWebview网页适配
微信 iOS 客户端自 2017 年 3 月 1 日起逐步升级为 WKWebView 内核,网页开发者需提前做好兼容检查和适配。如有疑问,可参考文末联系方式咨询。
# 背景
WKWebView 是苹果在 iOS 8 中引入的新组件,旨在提供更现代、支持最新 Webkit 功能的网页浏览控件,解决 UIWebView 内存占用大、性能低下等问题。WKWebView 使用与 Safari 相同的 Nitro JavaScript 引擎,极大提升了页面 JS 执行速度。
# 切换方法
自 iOS 微信 6.5.3 版本起,开发者可手动切换 WKWebView 和 UIWebView,以便提前适配。
手动切换入口:
在微信会话列表页点击右上角“加号按钮”,选择“添加朋友”,在搜索框输入“:switchweb”,点击键盘右下角搜索按钮。切换成功后会提示当前使用的内核(UIWebView 或 WKWebView)。
校验切换方法:
切换到 WKWebView 后,进入任意网页,加载成功后下拉页面(或点击右上角菜单按钮)显示地址栏。若地址栏以“此网页由”开头,则为 WKWebView;若为“网页由”,则为 UIWebView。
页面判断内核方式:
可通过微信注入的 window.__wxjs_is_wkwebview
变量判断当前内核。iOS 微信 6.5.3 及以后版本,window.__wxjs_is_wkwebview
为 true 时为 WKWebView,为 false 或 undefined 时为 UIWebView。
前端适配关注要点:
适配首要原则:若无法区分是 WKWebView 新特性还是微信内部逻辑导致页面异常,可分别在 Safari 和微信 WKWebView 内核下测试,快速定位问题。
# 适配指南
切换为 WKWebView 后,微信 WebView 行为与 Safari 高度一致,唯一不同是微信 WebView 注入了 JSBridge 脚本。适配重点关注以下方面:
- 页面功能是否正常
- 页面屏幕适配是否正常
- 页面行为是否正常(如返回按钮逻辑)
- 页面语法兼容性
- JSSDK 是否正常工作
- Cookie 和 LocalStorage 相关逻辑
- 服务器 Cache-Control 缓存逻辑
一般情况下无需特别适配,但如涉及以下受影响逻辑,请根据建议进行适配和确认。
1. 不再支持 cache
- 变化:WKWebView 暂不支持 cache jsapi。
- 适配建议:移除相关页面逻辑。
2. LocalID 预览图片
- 变化:JSSDK 1.2.0 以下版本不再支持通过 chooseImage 返回的 localId 以
img src=wxLocalResource://...
方式预览图片。 - 适配建议:升级 JSSDK 至 1.2.0 及以上版本,或使用 getLocalImgData 接口获取数据。
JSSDK 1.2.0 下载地址
3. wx.config 授权后 jsapi 调用失败问题
- 变化:WKWebView 内部实现变更,jsapi 权限管理逻辑调整,极小概率出现授权正常但 jsapi 调用失败。
- 适配建议:
- iOS 微信 6.5.1:如页面使用 HTML5 History API(pushState、popstate、replaceState)并用 wx.config 授权,可能出现 jsapi 无权限调用失败。建议用 Anchor hash 技术替代 History 技术。
- iOS 微信 6.5.2 及以后版本:上述问题已修复,但如页面涉及 history 或 hash 技术,仍需关注相关问题。
4. Cookie 和 LocalStorage 设置相关
退出微信账号后,将清空所有 Cookie 和 LocalStorage。页面依赖 Cookie 或相关逻辑时需注意:
变化1:跨域存取 Cookie
问题:页面 A 引用不同域名的页面 B 资源,B 设置 Cookie 时会被 WKWebView 阻止第三方跨域设置 Cookie 的安全策略拦截。
适配建议:通过业务后台存储需传递的信息,给页面分配 access_token,通过 URL 传递信息。变化2:微信原生层网络请求无法读取 WKWebView 设置的 Cookie(即使域名相同)
问题:如资源或图片服务器依赖 Cookie 校验,切换 WKWebView 后,长按保存或预览大图时原生请求不会带上 Cookie,导致保存或预览失败。
适配建议:建议静态资源 cookie free。如需传递信息,同样通过后台存储并用 access_token 方式传递。
除上述两种情况外,其他请求均会带上完整 Cookie,无需担心 Cookie 丢失。
5. 页面视频小窗播放
- 变化:iOS 微信 6.5.3 及以后版本,WebView 默认支持小窗播放。开发者需要特别注意小窗播放需要前端同时适配iOS10和iOS10以下的低版本
- 适配建议:需兼容 iOS10 及以下版本,video 标签需如下设置:
<video webkit-playsinline playsinline> </video>
6. WKWebview页面行为与Safari完全一致,会导致页面依赖UIWebview页面行为的逻辑失效或异常
可根据业务自身逻辑,实现测试页面后分别在Safari和微信WKWebview中验证
- Safari或微信WKWebview中,页面A跳转到页面B再返回页面A后不会重新执行Script和Ajax(也不会触发页面reload),但会触发页面的pageshow pageHide等事件。
- Safari或微信WKWebview中,在页面弹出输入键盘后,会触发JQuery的resize事件,而在UIWebView下不会。
- Safari或微信WKWebview中,window unload 事件在只有刷新才能触发,退出页面或者跳转到其他页面都无法触发。
- Safari或微信WKWebview中,极少数情况下某些特殊实现的页面点击事件会失效。
# 其他问题
- 页面自定义重载标准方法或者函数时,需要确保不会与微信注入Webview中的JSBridge相关方法冲突,否则会导致页面在微信中的行为异常。
- 强烈建议不要在无法确保页面缓存策略和逻辑与服务器逻辑完全保持一致的情况下冒然设置html页面文件(除了html类型的页面,页面引用的其他资源或脚本按照自身业务合理设置即可)相关的Cache-Control属性。
- 使用WKWebView,在单页应用中通过document.title多次修改原生title的方法将失效,该问题将于微信3月份发布的版本中解决。
- 在WKWebView中,表单form的method='post'并且target='_blank',会导致submit时网络请求的post数据丢失。解决方案是:判断如果是在微信中,且form的method为'post',则target改为'_self'。
典型案例
如果第一次访问页面A.html 服务器302跳转到A1.html?uid=111设置Cache-Control: max-age=60,此A1.html的uid参数是服务器设置的111(此时A1.html已经被客户端缓存)。 第二次访问页面A.html ,服务器同样302跳转到A1.html?uid=222,但是此时的A1.html页面的uid参数是222, 客户端带参数完整链接询问服务器缓存是否可用, 服务器返回缓存可用304,但是客户端缓存的A1.html完整链接带的uid参数是111,所以本地找不到数据,此时加载页面就会失败。