使用小程序框架(Taro)进行多端开发的实践

2,074 阅读7分钟

前言

小程序是一种基于App微信的web化解决方案,规范由微信开发团队定制

h5是指基于HTML5标准的技术,依赖于ECMAScript与w3c规范

请不要将h5和小程序混为一谈

仅仅从开发者的角度来看,小程序把web社区的各种成果和标准私有化,是违反发展趋势的

背景

虽然使用Taro进行多端开发,但是本文与taro关系不大,主要探究小程序与h5的差异化,还有前后端配合上的需要注意的事项

小程序与h5原理的不同

渲染方式不同

h5的加载完全受限于网络,加载不出来就会出现长时间白屏的情况

小程序使用的是双线程模式,一个线程处理页面,一个线程处理数据,所以在网络不好的情况下,也能很快的显示出页面,后面再逐渐完成数据的请求,具体请看渲染层和逻辑层

运行环境的不同

H5的运行环境是浏览器,包括webview,而微信小程序的运行环境并非完整的浏览器,因为小程序的开发过程中只用到一部分H5技术。

小程序的运行环境是微信开发团队基于浏览器内核完全重构的一个内置解析器针对性做了优化,配合自己定义的开发语言标准,提升了小程序的性能。

官方文档表明脚本内无法使用浏览器中常用的window对象和document对象,所以dom操作类框架都无法在小程序类使用(例如jquery)

开发成本不同

H5 的开发,涉及开发工具(vscode、Atom等)、前端框架(Vue、react等)、模块管理工具(Webpack 、Browserify 等)、任务管理工具(Grunt、Gulp等),还有UI库选择接口调用工具(ajax、Fetch Api等)、浏览器兼容性等等。这方面需要考虑的比小程序需要考虑的多得多

微信小程序开发由于微信团队提供了开发者工具,并且规范了开发标准,则简单得多

前端常见的HTML、CSS变成了微信自定义的WXML、WXSS,WXML,官方文档中都有明确的使用介绍

需要调用后端接口时,调用发起请求API;

需要上传下载时,调用上传下载API;

需要数据缓存时,调用本地存储API;

引入地图、使用罗盘、调用支付、调用扫码等等功能都可以直接使用;

UI库方面,框架带有自家weui库加成。

并且在使用这些API时,不用考虑浏览器兼容性,不用担心出现BUG,只需要考虑对手机不同型号的适配,显而易见微信小程序的开发成本相对较低。

小程序与h5开发上的不同

开发工具不同

h5的开发工具无要求+浏览器调试工具即可

小程序有自己独有的开发工具,对于调试,编译,预览,上传,发布都有自己的一套方案

开发语言不同

h5端为 HTML+CSS+JavaScript

小程序端为 WXML + WXSS + ECMAScript(不包含BOM,DOM)

组件封装不同

h5所有的组件,例如,底部下拉框,导航栏,所有视图相关都是需要写,或者使用开源产品

小程序自带很多APP组件,就例如h5的alert,但是小程序封装了很多,例如picker(底部弹出框)swiper(轮播图)showModal(弹窗),等等

标签写法不同

h5端依照html5规范 为div span p input img 等等

小程序是自身设计的一套标签语言 为 view text input image等高级组件,标签与html不完全相同

相信到这里,明显可以感觉到,小程序与h5看似是一个东西,但是具体上存在巨大的差异,基本相当于

h5 与 android的关系

路由配置不同

h5端对于路由无任何限制,不使用任何框架的传统网页只要资源存在都是可以跳转过去

小程序需要根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。

等等........................

其他细节请看文档说明小程序与普通网页开发的区别

前后端交互上与h5的不同(重点)

前后端交互主要在于对请求方面的h5与小程序api的分析

这方面文档并没有进行详细说明,以下资料为收集与实践得出

小程序所有请求的api都不支持cookie机制

这个观点非常遗憾在官方文档里面怎么也找不到相关说明,只能看到小程序登录里面手动把自定义请求头带给了后台,从而推论出小程序不支持cookie机制,这也是与h5第一个比较的大的差异,就像登录必须用户手动触发一样,这一系列规范开发者无法控制

小程序request与h5(xhr请求)获取的请求头不一致

小程序的请求中不会处理后端返回的response header里面的信息

可以明显看到获取到了后端返回到的所有response header,这一点与w3c规范完全不相同

我们再看看相同的接口,在h5里面返回的信息

h5的请求中严格按照w3c规范,对response header的信息进行了严格的控制,通过查阅资料了解到以下规范

  1. 按照 W3C 规范,H5 端无法获取 response header 中 Set-Cookie、Set-Cookie2 这2个字段,对于跨域请求,允许获取的 response header 字段只限于“simple response header”和“Access-Control-Expose-Headers”**(详情

  2. 在使用CORS解决跨域的请求中,默认只能取到

    Content-Language Content-Type Expires Last-Modified Pragma 五个reponse header 值。

    如果想获取到其他的值,需要服务器在header中设置

    Access-Control-Expose-Headers : sessionID , key1 , key2

为什么上面h5的请求中存在session呢?

因为在后端的请求头里面加了Access-Control-Expose-Headers : session

只有这样前端h5才能在使用cors解决跨域的情况下获取到后端的请求头里面的参数,否则h5这边是无法获取到response header里面的信息

这一点实践了,fetchaxios,这样最主流的请求方式与请求库

也实践了jquery的**$ajax**,因为他们在浏览器环境遵循w3c标准,所以得出的结果与以上理论一致

可以看到并不存在set-cookie的请求头

所以为了同时满足h5与小程序的多端开发,就需要各方面向下兼容

  1. 不使用w3c的cookie的方式,使用小程序的手动带给后端
  2. 不使用小程序返回的response header,因为需要兼容h5使用xhr的规范

从而得到当前阶段或许是最好的解决方案 自定义一个token,并设置Access-Control-Expose-Headers : token,这样就同时保证了h5与小程序,并统一了开发流程

上传文件上h5与小程序的不同

前后端分离的情况下 h5 使用xhr请求,定义请求头为multipart/form-data,即可上传文件到服务端

小程序使用的是wx.uploadFile,无其他参数设置

但是,这两个上传文件获取的结果却不同

h5

小程序

这里h5与微信小程序的api存在差异,所以后端需要在上传文件这个api需要按照微信这种方式来进行接口开发

开发细节上的不同

使用taro编译成h5之后,h5不存在头部导航栏

解决方案为自定义头部导航栏 这一点uniapp似乎做得好一点

小程序的主页面视口与h5不一样

小程序主页面的可操作区域不包含头部,底部导航栏

但是h5不论什么页面可操作区域是包含头部,底部导航栏,这一点开发中需要做平台代码判断,以免出现页面错乱的情况

​ 因为就像最开始的那句话,微信未遵循w3c定制的规范,而是用web领域多年的发展自成体系并商业化,所以出现了这种看似与h5一致,实际上存在很多规范不一样的的情况,作为开发者,如果需要同时完全双端的任务,最好的解决办法就是取其交集,这样才能保证任务的同时,还不影响开发进度