web-view 网页容器

解释:web-view 组件是一个可以用来承载网页的容器,会自动铺满整个智能小程序页面。navigationStyle: custom 对 web-view 组件无效

属性说明

属性名类型默认值必填说明最低版本
srcStringweb-view 指向网页的链接-
bindmessageEventHandler网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data }1.12.0
低版本请做兼容性处理

使用 web-view 打开限定域名内的网页

访问智能小程序管理中心,进入对应的小程序管理后台,点击“设置 -> 开发设置 -> 业务域名”,即可在业务域名中下载、配置校验文件并配置业务域名。

web-view 网页容器 - 图1

如何在根目录下放置校验文件?

举例:小程序 appid = 123456

  1. 配置域名为:https://a.baidu.com 则需要把校验文件放置到 a.baidu.com 域名下,最后的链接地址为:https://a.baidu.com/bd\_mapp\_domaincer\_123456.txt

  2. 配置域名为:https://baidu.com 则需要把校验文件放置到 baidu.com 域名下,最后的链接地址为:https://baidu.com/bd\_mapp\_domaincer\_123456.txt

  3. 配置域名为:https://xx.bb.baidu.com 则需要把校验文件放置到 xx.bb.baidu.com 域名下,最后的链接地址为:https://xx.bb.baidu.com/bd\_mapp\_domaincer\_123456.txt

正确配置的情况下,这个txt文件应该是能够通过这些地址(如:https://a.baidu.com/bd\_mapp\_domaincer\_123456.txt)访问到的。配置后,页面打开的效果:
web-view 网页容器 - 图2

注意事项

  • 所有在 H5 页面(包括通过该页打开的其他 H5 页)出现的请求域名都需要进行上方的配置,含静态文件(js、css、图片等)
  • 当在开发者工具-项目信息-本地配置里不勾选校验域名时,可以在开发环境中临时关闭对域名的校验,但这个设置并不对线上小程序生效,即如果小程序发布上线前,没有在智能小程序管理中心进行上方的配置,那线上访问这些页面时将依然出现异常,提示出错
    web-view 网页容器 - 图3

示例

在开发者工具中打开

在开发者工具中打开

在 WEB IDE 中打开

扫码体验

代码示例

百度智能小程序

请使用百度APP扫码

代码示例

跳转页面

  • SWAN
  • JS
  1. <view class="wrap">
  2. <button type="primary" bindtap="toWebView">点击进入 H5 页面</button>
  3. </view>
  1. Page({
  2. // onLoad 时接收 H5 页传过来的参数,可写在承载 web-view 的小程序页,也可以写在非 web-view 页,此处为非 web-view 页示例
  3. onLoad(options) {
  4. if (options.key) {
  5. swan.showToast({
  6. title: `接受到来自H5页的参数为:${options.key}`,
  7. icon: 'none'
  8. });
  9. console.log('接受到来自H5页的参数为', options); // {key: 'fromWebview'}
  10. }
  11. },
  12. toWebView() {
  13. // 进入 H5 页
  14. swan.navigateTo({
  15. url: '/index/index'
  16. })
  17. }
  18. });

web-view 页面

  • SWAN
  • JS
  1. <web-view src="{{src}}" bindmessage="postMessage"></web-view>
  1. Page({
  2. data: {
  3. src: `https://smartprogram.baidu.com/docs/html/web-view/web-view.html?${encodeURIComponent('中文参数=value')}`
  4. },
  5. // onLoad 时接收H5页传过来的参数,刷新本 H5 页的时候,也可以接收
  6. onLoad(options) {
  7. // 这里Key为示例,可更换为其他
  8. if (options.key) {
  9. swan.showToast({
  10. title: `接受到来自H5页的参数为:${options.key}`,
  11. icon: 'none'
  12. });
  13. // {key: 'fromWebview'}
  14. console.log('接受到来自H5页的参数为', options);
  15. }
  16. // 分享出去的收口机制,相当于刷新
  17. if (options.path) {
  18. swan.showToast({
  19. title: `小程序分享回流后打开的H5页为:${options.path}`,
  20. icon: 'none'
  21. });
  22. this.setData('src', options.path);
  23. }
  24. },
  25. // web-view 通过 swan.webView.postMessage 向小程序发送消息,小程序通过 bindmessage 事件来监听网页向小程序发送的消息,接收时机:小程序后退、组件销毁、分享时
  26. postMessage(options) {
  27. swan.showToast({
  28. title: '接收到了H5发送的message,详细信息请到控制台查看',
  29. icon: 'none'
  30. })
  31. console.log('H5页传过来的参数为:', options);
  32. // options 为
  33. // {
  34. // currentTarget: {
  35. // id: '_5302',
  36. // offsetLeft: 0,
  37. // offsetTop: 0,
  38. // dataset: {}
  39. // },
  40. // detail: {
  41. // data:["foo"]
  42. // },
  43. // 'target': {
  44. // id: '_5302',
  45. // offsetLeft: 0,
  46. // offsetTop: 0,
  47. // dataset: {}
  48. // },
  49. // timeStamp: 8,
  50. // type: "message",
  51. // }
  52. },
  53. onShareAppMessage(options) {
  54. // 获取当前<web-view>的URL, 真机可以,工具暂不能返回此字段
  55. console.log('H5页的url', options.webViewUrl);
  56. return {
  57. title: '智能小程序官方示例',
  58. content: '世界很复杂,百度更懂你——小程序简介或详细描述',
  59. imageUrl: 'https://b.bdstatic.com/miniapp/images/bgt_icon.png',
  60. // 此处写小程序页面path
  61. path: `/index/index?path=${options.webViewUrl}`,
  62. success(res) {
  63. // 分享成功
  64. },
  65. fail(err) {
  66. // 分享失败
  67. }
  68. };
  69. }
  70. });

H5 页面

  • SWAN
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  5. <title>web-view</title>
  6. <script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.22.js"></script>
  7. </head>
  8. <body>
  9. <div class="node">
  10. <h2>相关接口1</h2>
  11. <h3>onLoad接收参数</h3>
  12. <button type="button" id="navToSmart">点我跳转小程序其他页</button>
  13. <button type="button" id="refresh">点我刷新</button>
  14. <button type="button" id="isSmartApp">是否运行在小程序中</button>
  15. <h3>小程序接收web-view传过来的参数</h3>
  16. <button type="button" id="postMessage">点击向小程序发送消息</button>
  17. <button type="button" id="back">小程序后退</button>
  18. <button type="button">请点击右上方胶囊分享</button>
  19. <h2>相关接口2</h2>
  20. <button type="button" id="makePhoneCall">点击拨打电话</button>
  21. <button type="button" id="setClipboardData">设置剪贴板</button>
  22. <button type="button" id="getNetworkType">获取网络类型</button>
  23. <button type="button" id="openShare">分享</button>
  24. <button type="button" id="navigateToSmartProgram">打开小程序</button>
  25. <button type="button" id="openLocation">打开地图查看当前位置</button>
  26. <button type="button" id="getLocation">获取当前地理位置</button>
  27. <button type="button" id="chooseImage">拍照或上传</button>
  28. <button type="button" id="previewImage">预览图片</button>
  29. <button type="button" id="login">用户登陆</button>
  30. <h2>相关接口3</h2>
  31. <button type="button">请点击右上方胶囊分享</button>
  32. <h2>功能1:H5页面之间跳转有返回按钮</h2>
  33. <button type="button" id="toH5">点击跳转到另一个 H5 页面</button>
  34. </div>
  35. </body>
  36. <script type="text/javascript">
  37. /* globals swan */
  38. // 页面加载时判断是否在小程序环境中
  39. const isSmartApp = function () {
  40. // 写法一
  41. swan.webView.getEnv(function (res) {
  42. console.log(res.smartprogram);
  43. alert(`当前页面是否运行在小程序中:${res.smartprogram}`); // true
  44. });
  45. // 写法二
  46. // const isWebView = /swan\//.test(window.navigator.userAgent) || /^webswan-/.test(window.name);
  47. // alert(`当前页面是否运行在小程序中:${isWebView}`); // true
  48. };
  49. // 跳转回小程序页面
  50. const navToSmart = function () {
  51. // swan.webView.switchTab
  52. // swan.webView.reLaunch
  53. // swan.webView.navigateTo
  54. swan.webView.redirectTo({
  55. url: '/component/to-web-view/to-web-view?key=fromWebview',
  56. success() {
  57. console.log('to-web-view success');
  58. },
  59. fail() {
  60. console.log('fail');
  61. }
  62. });
  63. swan.webView.postMessage({data: 'foo'});
  64. };
  65. // H5页面重新刷新带参数
  66. const refresh = function () {
  67. console.log('refresh');
  68. swan.webView.redirectTo({
  69. url: '/component/webview/webview?key=refresh',
  70. success() {
  71. console.log('to-web-view');
  72. },
  73. fail() {
  74. console.log('fail');
  75. }
  76. });
  77. };
  78. // H5页面向小程序发送消息
  79. const postMessageHandler = function () {
  80. swan.webView.postMessage({
  81. data: {
  82. key: 'message'
  83. }
  84. });
  85. };
  86. // H5页面返回上级小程序页面
  87. const backHandler = function () {
  88. swan.webView.navigateBack();
  89. };
  90. document.getElementById('navToSmart').onclick = navToSmart;
  91. document.getElementById('isSmartApp').onclick = isSmartApp;
  92. document.getElementById('refresh').onclick = refresh;
  93. document.getElementById('postMessage').onclick = postMessageHandler;
  94. document.getElementById('back').onclick = backHandler;
  95. // 调用拨打电话API
  96. const makePhoneCallHandler = function () {
  97. swan.makePhoneCall({
  98. phoneNumber: '(0313)xxxx xxxx',
  99. success: res => {
  100. console.log('res', res);
  101. },
  102. fail: err => {
  103. alert('拨打失败,请检查是否输入了正确的电话号码');
  104. }
  105. });
  106. };
  107. // 调用剪贴板API
  108. const setClipboardDataHandler = function () {
  109. swan.setClipboardData({
  110. data: 'originData',
  111. success: res => {
  112. alert('设置成功,剪贴板内容为originData');
  113. },
  114. fail: err => {
  115. alert('设置失败');
  116. }
  117. });
  118. };
  119. // 调用网络类型API
  120. const getNetworkTypeHandler = function () {
  121. swan.getNetworkType({
  122. success: res => {
  123. alert(`当前网络状态为${res.networkType}`);
  124. console.log('getNetworkTypeHandler', res.networkType);
  125. },
  126. fail: err => {
  127. alert('获取网络类型失败');
  128. }
  129. });
  130. };
  131. // 调用分享API
  132. const openShareHandler = function () {
  133. swan.openShare({
  134. title: '智能小程序示例',
  135. content: '世界很复杂,百度更懂你',
  136. path: 'swan-api/open-share/open-share?key=value',
  137. imageUrl: 'https://smartprogram.baidu.com/docs/img/logo_new.png',
  138. success: res => {
  139. alert('分享成功');
  140. console.log('openShare success', res);
  141. },
  142. fail: err => {
  143. alert('分享失败');
  144. console.log('openShare fail', err);
  145. }
  146. });
  147. };
  148. // 调用打开另一个小程序API
  149. const navigateToSmartProgramHandler = function () {
  150. swan.navigateToSmartProgram({
  151. // 打开目标小程序的AppKey,开发版AppKey可在开发者工具中预览获取
  152. appKey: 'sc9Tq1iKawTnj5GhG6i77vzeIt4Crt5u',
  153. success: res => {
  154. console.log('navigateToSmartProgram success', res);
  155. },
  156. fail: err => {
  157. alert('打开失败');
  158. console.log('navigateToSmartProgram fail', err);
  159. }
  160. });
  161. };
  162. // 调用打开地图API
  163. const openLocationHandler = function () {
  164. swan.openLocation({
  165. latitude: 40.04,
  166. longitude: 116.27,
  167. scale: 18,
  168. name: '百度科技园',
  169. address: '北京市海淀区西北旺东路10号院',
  170. success: res => {
  171. alert('打开成功');
  172. console.log('openLocation success', res);
  173. },
  174. fail: err => {
  175. alert('打开失败');
  176. console.log('openLocation fail', err);
  177. }
  178. });
  179. };
  180. // 调用获取地图位置API
  181. const getLocationHandler = function () {
  182. swan.getLocation({
  183. type: 'gcj02',
  184. altitude: true,
  185. success: res => {
  186. alert('打开成功,详细信息请到控制台查看');
  187. console.log('getLocation success', res);
  188. },
  189. fail: err => {
  190. alert('打开失败');
  191. }
  192. });
  193. };
  194. // 调用选择图片API
  195. const chooseImageHandler = function () {
  196. swan.chooseImage({
  197. count: 9,
  198. sizeType: ['original'],
  199. sourceType: ['camera'],
  200. success: res => {
  201. console.log('res.tempFilePaths', res.tempFilePaths);
  202. },
  203. fail: err => {
  204. alert('接口调用失败');
  205. console.log('chooseImage fail', err);
  206. }
  207. });
  208. };
  209. // 调用预览图片API
  210. const previewImageHandler = function () {
  211. swan.previewImage({
  212. current: 'https://b.bdstatic.com/miniapp/image/swan-preview-image-2-zip.png', // current需与urls中链接一致
  213. urls: ['https://b.bdstatic.com/miniapp/image/swan-preview-image-2-zip.png'],
  214. success: res => {
  215. console.log('previewImage success');
  216. },
  217. fail: err => {
  218. alert('打开失败');
  219. console.log('previewImage fail', err);
  220. }
  221. });
  222. };
  223. // 调用登录API
  224. const loginHandler = function () {
  225. swan.login({
  226. success: res => {
  227. alert('已登录');
  228. console.log('login success', res);
  229. },
  230. fail: err => {
  231. alert('登录失败');
  232. console.log('login fail', err);
  233. }
  234. });
  235. };
  236. document.getElementById('makePhoneCall').onclick = makePhoneCallHandler;
  237. document.getElementById('setClipboardData').onclick = setClipboardDataHandler;
  238. document.getElementById('getNetworkType').onclick = getNetworkTypeHandler;
  239. document.getElementById('openShare').onclick = openShareHandler;
  240. document.getElementById('navigateToSmartProgram').onclick = navigateToSmartProgramHandler;
  241. document.getElementById('openLocation').onclick = openLocationHandler;
  242. document.getElementById('getLocation').onclick = getLocationHandler;
  243. document.getElementById('chooseImage').onclick = chooseImageHandler;
  244. document.getElementById('previewImage').onclick = previewImageHandler;
  245. document.getElementById('login').onclick = loginHandler;
  246. // 将跳转提升至小程序层面
  247. const toH5Handler = function () {
  248. swan.webView.navigateTo({
  249. // 带不同的query展示不同页面
  250. url: '/component/webview/webview?weburl=2'
  251. });
  252. };
  253. document.getElementById('toH5').onclick = toH5Handler;
  254. </script>
  255. </html>

相关接口介绍

Web 态说明

JSSDK 2.0.21 以上版本支持 Web 态环境。

相关接口 1

web-view 网页中可使用 JSSDK 提供的接口返回智能小程序页面。 支持的接口有:

旧版本 swan.xxxx,已更新为 swan.webView.xxxx。

接口名说明
swan.webView.navigateTo参数与智能小程序接口一致
swan.webView.navigateBack参数与智能小程序接口一致
swan.webView.switchTab参数与智能小程序接口一致
swan.webView.reLaunch参数与智能小程序接口一致
swan.webView.redirectTo参数与智能小程序接口一致
swan.webView.getEnv获取当前环境
swan.webView.postMessage向小程序发送消息

代码示例

  • SWAN
  • JS
  1. <!-- html -->
  2. <script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.22.js"></script>
  1. // javascript
  2. swan.webView.navigateTo({url: '/pages/detail/index'});
  3. swan.webView.postMessage({data: 'foo'});
  4. swan.webView.postMessage({data: {foo: 'bar'} });
  5. // 如何判断 H5 页面是否在小程序 web-view 打开:
  6. // 方法1:
  7. swan.webView.getEnv(function(res) {console.log(res.smartprogram);}); // true
  8. // isWebView 若为 true,则是在小程序的 web-view 中打开
  9. // 方法2:
  10. const isWebView = /swan\//.test(window.navigator.userAgent) || /^webswan-/.test(window.name);

相关接口 2

web-view 网页中支持的接口有:

接口模块接口说明具体接口备注
设备拨打电话swan.makePhoneCall
设备设置剪贴板swan.setClipboardData
设备获取网络类型swan.getNetworkType
位置使用内置地图查看位置swan.openLocation
位置获取地理位置swan.getLocation
媒体拍照或上传swan.chooseImage
媒体预览图片swan.previewImage
用户接口分享swan.openShare需传入当前要分享的小程序的 appKey
用户接口打开小程序swan.navigateToSmartProgram2.0.18 版本开始,支持使用 envVersion 打开不同版本的小程序
开放接口登录swan.login

相关接口 3

用户分享时可获取当前 web-view 的 URL,即在 onShareAppMessage 回调中返回 webViewUrl 参数,参见上方代码示例

Bug & Tip

  • Tip:网页内 iframe 的域名也需要配置到域名白名单。
  • Tip:每个页面只能有一个web-viewweb-view会自动铺满整个页面,并覆盖其他组件。
  • Tip:网页与智能小程序之间不支持除 JSSDK 提供的接口之外的通信,如果使用了 JSSDK 提供的接口,需要引入swanjs,参见上方相关接口 1 - 代码示例
  • Tip:避免给web-view组件设置的网页链接中带有中文字符,在 iOS 中会有打开白屏的问题,建议做一下 encodeURIComponent ,参见上方代码示例

常见问题

Q:如何在 web-view 中使用拨打电话的功能或接口?

A:如果想在 web-view 使用 JSSDK 提供的接口能力,需要引入 swanjs 包,请参考代码示例 - H5 页面

“2.0.21.js”版本为举例,开发时请参考相关接口 1 - 代码示例中的最新版本号进行填写。

生成的 H5 站点地址放入小程序 web-view 的 src 即可。

Q:在 web-view 中使用了 cookie ,导致存储信息与小程序不能共享的原因是什么?

A:web-view 网页与小程序之间不支持除 JSSDK 提供的接口之外的通信:

  1. 小程序中如需设置 cookie 建议使用 Storage
  2. 如需传递小程序参数到 web-view 组件的 H5 页面中, 可加在 web-view 的 src 后。

Q:小程序使用 web-view ,分享时 path 字段指定的链接能直接是 web-view 对应的 url 而不是小程序的 path 吗?

A:不能,使用 onShareAppMessage 或者 swan.openShare 进行分享时,path只能设置为小程序页面的 path ,不能设置为 H5 页面的 url ,若想回到对应的 H5 页,参见上方代码示例 - 跳转页面