MUI开发注意事项
DOM结构
关于mui页面的dom,你需要知道如下规则。
固定栏靠前
所谓的固定栏,也就是带有.mui-bar属性的节点,都是基于fixed定位的元素;常见组件包括:顶部导航栏(.mui-bar-nav)、底部工具条(.mui-bar-footer)、底部选项卡(.mui-bar-tab);这些元素使用时需遵循一个规则:放在.mui-content元素之前,即使是底部工具条和底部选项卡,也要放在.mui-content之前,否则固定栏会遮住部分主内容;
一切内容都要包裹在mui-content中
除了固定栏之外,其它内容都要包裹在.mui-content中,否则就有可能被固定栏遮罩,原因:固定栏基于Fixed定位,不受流式布局限制,普通内容依然会从top:0的位置开始布局,这样就会被固定栏遮罩,mui为了解决这个问题,定义了如下css代码:
.mui-bar-nav ~ .mui-content {
padding-top: 44px;
}
.mui-bar-footer ~ .mui-content {
padding-bottom: 44px;
}
.mui-bar-tab ~ .mui-content {
padding-bottom: 50px;
}
你当然可以通过自定义CSS的方式实现如上类似效果,但为了使用简便,建议将除固定栏之外的所有内容,全部放在.mui-content中。
始终为button按钮添加type属性
若button按钮没有type属性,浏览器默认按照type=submit逻辑处理,这样若将没有type的button放在form表单中,点击按钮就会执行form表单提交,页面就会刷新,用户体验极差。
窗口管理
页面初始化:必须执行mui.init方法
mui在页面初始化时,初始化了很多参数配置,比如:按键监听、手势监听等,因此mui页面都必须调用一次mui.init()方法;
页面跳转:抛弃href跳转
当浏览器加载一个新页面时,若页面DOM尚未渲染完毕,页面会先显示空白,然后等DOM渲染完毕后,再显示具体内容,这是WEB浏览器技术无法逾越的体验障碍;为解决这个问题,建议使用mui.openWindow方法打开一个新的webview,mui会自动监听新页面的loaded事件,若加载完毕,再自动显示新页面;
扩展阅读:
页面关闭:勿重复监听backbutton
mui框架自动封装了页面关闭逻辑,若希望自定义返回逻辑(例如编辑页面的返回,需用户确认放弃草稿后再执行返回逻辑),则需要重写mui.back方法,切勿简单通过addEventListener添加backbutton监听,因为addEventListener只会增加新的执行程序,mui默认封装的监听执行逻辑依然会继续执行,因此若仅addEventListener添加用户确认框,则用户即使选择了取消,也会继续关闭窗口。
手势操作
点击:忘记click
快速响应是mobile App实现的重中之重,研究表明,当延迟超过100毫秒,用户就能感受到界面的卡顿,然而手机浏览器的click点击存在300毫秒延迟(至于为何会延迟,及300毫秒的来龙去脉,请自行谷百),mui为了解决这个问题,封装了tap事件,因此在任何点击的时候,请忘记click及onclick操作,统统使用如下代码:
element.addEventListener('tap',function(){
//点击响应逻辑
});
常见错误
Uncaught ReferenceError: plus is not defined
在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,否则可能会报“plus is not defined”的错误;
mui为简化开发,将plusReady事件封装成了mui.plusReady()方法,凡涉及到HTML5+的api,建议都写在mui.plusReady方法中;
DOM结构
关于mui页面的dom,你需要知道如下规则。
固定栏靠前
所谓的固定栏,也就是带有.mui-bar属性的节点,都是基于fixed定位的元素;常见组件包括:顶部导航栏(.mui-bar-nav)、底部工具条(.mui-bar-footer)、底部选项卡(.mui-bar-tab);这些元素使用时需遵循一个规则:放在.mui-content元素之前,即使是底部工具条和底部选项卡,也要放在.mui-content之前,否则固定栏会遮住部分主内容;
一切内容都要包裹在mui-content中
除了固定栏之外,其它内容都要包裹在.mui-content中,否则就有可能被固定栏遮罩,原因:固定栏基于Fixed定位,不受流式布局限制,普通内容依然会从top:0的位置开始布局,这样就会被固定栏遮罩,mui为了解决这个问题,定义了如下css代码:
.mui-bar-nav ~ .mui-content {
padding-top: 44px;
}
.mui-bar-footer ~ .mui-content {
padding-bottom: 44px;
}
.mui-bar-tab ~ .mui-content {
padding-bottom: 50px;
}
你当然可以通过自定义CSS的方式实现如上类似效果,但为了使用简便,建议将除固定栏之外的所有内容,全部放在.mui-content中。
始终为button按钮添加type属性
若button按钮没有type属性,浏览器默认按照type=submit逻辑处理,这样若将没有type的button放在form表单中,点击按钮就会执行form表单提交,页面就会刷新,用户体验极差。
窗口管理
页面初始化:必须执行mui.init方法
mui在页面初始化时,初始化了很多参数配置,比如:按键监听、手势监听等,因此mui页面都必须调用一次mui.init()方法;
页面跳转:抛弃href跳转
当浏览器加载一个新页面时,若页面DOM尚未渲染完毕,页面会先显示空白,然后等DOM渲染完毕后,再显示具体内容,这是WEB浏览器技术无法逾越的体验障碍;为解决这个问题,建议使用mui.openWindow方法打开一个新的webview,mui会自动监听新页面的loaded事件,若加载完毕,再自动显示新页面;
扩展阅读:
页面关闭:勿重复监听backbutton
mui框架自动封装了页面关闭逻辑,若希望自定义返回逻辑(例如编辑页面的返回,需用户确认放弃草稿后再执行返回逻辑),则需要重写mui.back方法,切勿简单通过addEventListener添加backbutton监听,因为addEventListener只会增加新的执行程序,mui默认封装的监听执行逻辑依然会继续执行,因此若仅addEventListener添加用户确认框,则用户即使选择了取消,也会继续关闭窗口。
手势操作
点击:忘记click
快速响应是mobile App实现的重中之重,研究表明,当延迟超过100毫秒,用户就能感受到界面的卡顿,然而手机浏览器的click点击存在300毫秒延迟(至于为何会延迟,及300毫秒的来龙去脉,请自行谷百),mui为了解决这个问题,封装了tap事件,因此在任何点击的时候,请忘记click及onclick操作,统统使用如下代码:
element.addEventListener('tap',function(){
//点击响应逻辑
});
常见错误
Uncaught ReferenceError: plus is not defined
在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,否则可能会报“plus is not defined”的错误;
mui为简化开发,将plusReady事件封装成了mui.plusReady()方法,凡涉及到HTML5+的api,建议都写在mui.plusReady方法中;
5+ API模块化分类
| 所有5+ API都是按照模块化分类实现,在App云端打包时会根据应用中使用5+ API自动选择使用对于的模块进行打包,以优化生成安装包(apk或ipa)的尺寸。 5+ API模块化分类如下: |
模块名称 | 说明 | API |
|---|---|---|---|
| Accelerometer | 访问设备感应器 | plus.accelerometer | |
| Audio | 访问设备麦克风 | plus.audio | |
| Cache | 管理应用缓存 | plus.cache | |
| Camera | 访问摄像头设备 | plus.camera | |
| Contacts | 访问系统联系人信息 | plus.constacts | |
| Device | 访问设备信息 | plus.device,plus.display,plus.networkinfo,plus.screen | |
| Downloader | 管理文件下载任务 | plus.downloader | |
| File | 访问本地文件系统 | plus.io | |
| Gallery | 访问系统相册 | plus.gallery | |
| Geolocation | 获取设备位置信息 | plus.geolocation | |
| Messaging | 访问设备通讯能力 | plus.messaging | |
| NativeObj | 原生对象 | plus.nativeObj | |
| NativeUI | 原生UI控件 | plus.nativeUI | |
| Navigator | 浏览器信息 | plus.navigator | |
| Orientation | 获取设备方向信息 | plus.orientation | |
| Push | 管理消息推送能力 | plus.push | |
| Proximity | 获取距离感应器 | plus.proximity | |
| Storage | 管理应用本地数据 | plus.storage | |
| UI | (已过时不推荐使用)管理系统原生控件API | plus.navigator,plus.nativeUI,plus.webview | |
| Uploader | 管理文件上传任务 | plus.uploader | |
| Runtime | 访问运行期环境API | plus.runtime | |
| Webview | 窗口管理 | plus.webview | |
| XMLHttpRequest | 跨域网络访问API | plus.net | |
| Zip | 文件压缩与解压缩 | plus.zip | |
| Maps | 地图扩展功能 | plus.maps | |
| Barcode | 二维码功能 | plus.barcode | |
| Payment | 支付功能 | plus.payment | |
| Share | 分享功能 | plus.share | |
| Speech | 语音识别功能 | plus.speech | |
| Statistic | 统计功能 | plus.statistic |
| 所有5+ API都是按照模块化分类实现,在App云端打包时会根据应用中使用5+ API自动选择使用对于的模块进行打包,以优化生成安装包(apk或ipa)的尺寸。 5+ API模块化分类如下: |
模块名称 | 说明 | API |
|---|---|---|---|
| Accelerometer | 访问设备感应器 | plus.accelerometer | |
| Audio | 访问设备麦克风 | plus.audio | |
| Cache | 管理应用缓存 | plus.cache | |
| Camera | 访问摄像头设备 | plus.camera | |
| Contacts | 访问系统联系人信息 | plus.constacts | |
| Device | 访问设备信息 | plus.device,plus.display,plus.networkinfo,plus.screen | |
| Downloader | 管理文件下载任务 | plus.downloader | |
| File | 访问本地文件系统 | plus.io | |
| Gallery | 访问系统相册 | plus.gallery | |
| Geolocation | 获取设备位置信息 | plus.geolocation | |
| Messaging | 访问设备通讯能力 | plus.messaging | |
| NativeObj | 原生对象 | plus.nativeObj | |
| NativeUI | 原生UI控件 | plus.nativeUI | |
| Navigator | 浏览器信息 | plus.navigator | |
| Orientation | 获取设备方向信息 | plus.orientation | |
| Push | 管理消息推送能力 | plus.push | |
| Proximity | 获取距离感应器 | plus.proximity | |
| Storage | 管理应用本地数据 | plus.storage | |
| UI | (已过时不推荐使用)管理系统原生控件API | plus.navigator,plus.nativeUI,plus.webview | |
| Uploader | 管理文件上传任务 | plus.uploader | |
| Runtime | 访问运行期环境API | plus.runtime | |
| Webview | 窗口管理 | plus.webview | |
| XMLHttpRequest | 跨域网络访问API | plus.net | |
| Zip | 文件压缩与解压缩 | plus.zip | |
| Maps | 地图扩展功能 | plus.maps | |
| Barcode | 二维码功能 | plus.barcode | |
| Payment | 支付功能 | plus.payment | |
| Share | 分享功能 | plus.share | |
| Speech | 语音识别功能 | plus.speech | |
| Statistic | 统计功能 | plus.statistic |
Uncaught ReferenceError: mui is not defined
打开一个新窗口,使用mui.openWindow,然后报出mui is not defined,这个错误无法定位bug,折腾了好一会,最终发现是url写错了。
或许有谁也报了这种错误,然后找到错误原因,也贴在这下面,能减少我们这些新手很多困惑。
不知官方对于异常是否能优化一下,抛出更明确的错误信息。而不是现在这样的
打开一个新窗口,使用mui.openWindow,然后报出mui is not defined,这个错误无法定位bug,折腾了好一会,最终发现是url写错了。
或许有谁也报了这种错误,然后找到错误原因,也贴在这下面,能减少我们这些新手很多困惑。
不知官方对于异常是否能优化一下,抛出更明确的错误信息。而不是现在这样的
收起阅读 »如何扩展语法提示、自定义语法
HBuilder默认只提示标准的HTML5语法。很多框架有自己的HTML、JS语法,也希望在开发中被提示。
HBuilder提供如下扩展方案。
JS部分
- 基于sdocml的框架语法库
对工程点右键,引入框架语法,可以看到我们已经做了的一些常用框架语法库,包括jquery、zepto、mui。
其他框架语法,大家可参考这些语法库的sdocml文件格式,来自己做。
做好后提交到 https://github.com/dcloudio/WebFrameworkGrammar 以共享给更多开发者。 - jsdoc
HBuilder兼容jsdoc规范,如果开发者的jsdoc写的完善,一样可以被HBuilder的代码助手良好的提示出来。
jsdoc+的扩展规范地址:http://ask.dcloud.net.cn/article/129
jsdoc的好处是分发容易,跟着js文件一起分发;坏处是造成js文件体积变大,影响性能。
常见的做法是提供2个js文件给开发者,比如ext-dev.js和ext-min.js。dev包括jsdoc而min是压缩版。
另外注意js文件的体积,比如ext-dev.js的官方文件高达6M,这样的文件HBuilder解析起来还是有压力的。 - js代码块
我们也可以通过代码块的方式来扩展js提示。
点菜单工具-扩展代码块-js,可以看到详细说明和教程。
代码块并不是简单的xml配置,而是可以使用ruby编程的,功能很强大。
扩展的代码块,可以提交到 https://github.com/dcloudio/HBuilderRubyBundle 以共享给更多开发者。
HTML部分
HTML部分目前只能通过代码块扩展,代码块的扩展包括标签和属性2部分,在工具-扩展代码块-HTML里有说明。
扩展的代码块,可以提交到 https://github.com/dcloudio/HBuilderRubyBundle 以共享给更多开发者。
HBuilder默认只提示标准的HTML5语法。很多框架有自己的HTML、JS语法,也希望在开发中被提示。
HBuilder提供如下扩展方案。
JS部分
- 基于sdocml的框架语法库
对工程点右键,引入框架语法,可以看到我们已经做了的一些常用框架语法库,包括jquery、zepto、mui。
其他框架语法,大家可参考这些语法库的sdocml文件格式,来自己做。
做好后提交到 https://github.com/dcloudio/WebFrameworkGrammar 以共享给更多开发者。 - jsdoc
HBuilder兼容jsdoc规范,如果开发者的jsdoc写的完善,一样可以被HBuilder的代码助手良好的提示出来。
jsdoc+的扩展规范地址:http://ask.dcloud.net.cn/article/129
jsdoc的好处是分发容易,跟着js文件一起分发;坏处是造成js文件体积变大,影响性能。
常见的做法是提供2个js文件给开发者,比如ext-dev.js和ext-min.js。dev包括jsdoc而min是压缩版。
另外注意js文件的体积,比如ext-dev.js的官方文件高达6M,这样的文件HBuilder解析起来还是有压力的。 - js代码块
我们也可以通过代码块的方式来扩展js提示。
点菜单工具-扩展代码块-js,可以看到详细说明和教程。
代码块并不是简单的xml配置,而是可以使用ruby编程的,功能很强大。
扩展的代码块,可以提交到 https://github.com/dcloudio/HBuilderRubyBundle 以共享给更多开发者。
HTML部分
HTML部分目前只能通过代码块扩展,代码块的扩展包括标签和属性2部分,在工具-扩展代码块-HTML里有说明。
扩展的代码块,可以提交到 https://github.com/dcloudio/HBuilderRubyBundle 以共享给更多开发者。
iOS平台设置沉浸式状态栏显示效果
系列文章导航:
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台设置沉浸式状态栏显示效果
iOS平台设置沉浸式状态栏显示效果
正文:
应用可视区域到系统状态栏下透明显示效果,如下图所示:

此模式下应用占用全屏区域,而系统状态栏会拦截用户操作事件,此时需要预留出系统状态栏高度。
获取系统状态栏高度及沉浸式状态判断参考:如何动态判断沉浸式状态栏模式。
HBuilder创建的应用默认不使用沉浸式状态栏样式,需要进行如下配置开启:
打开应用的manifest.json文件,切换到代码视图,在plus -> statusbar 下添加immersed节点并设置值为true。
"plus": {
"statusbar": {
"immersed": true
}
}
如下图所示:
保存后提交App云端打包
注意事项:
- 真机运行不生效,需提交App云端打包后才生效;
- 此功能仅在iOS7及以上系统有效。
3. 设置沉浸式状态栏后顶部有灰条的问题解决
iOS11以上系统当启用沉浸式式状态栏后,webview默认会调整内容至安全区域之内,视觉效果如下图:
如果不需要自动调整可以在meta(name="viewport")节点的content属性值中添加viewport-fit=cover
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
iOS平台5+SDK原生环境配置方法
Android平台设置沉浸式状态栏显示效果
系列文章导航:
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
Android平台设置沉浸式状态栏显示效果
iOS平台设置沉浸式状态栏显示效果
正文:
应用可视区域到系统状态栏下透明显示效果,如下图所示:

此模式下应用占用全屏区域,而系统状态栏会拦截用户操作事件,此时需要预留出系统状态栏高度。
获取系统状态栏高度及沉浸式状态判断参考:如何动态判断沉浸式状态栏模式。
HBuilder创建的应用默认不使用沉浸式状态栏样式,需要进行如下配置开启:
打开应用的manifest.json文件,切换到代码视图,在plus -> statusbar 下添加immersed节点并设置值为true。
"plus": {
"statusbar": {
"immersed": true
}
}
如下图所示:
保存后提交App云端打包
注意事项:
- 真机运行不生效,需提交App云端打包后才生效;
- 此功能仅在iOS7及以上系统有效。
3. 设置沉浸式状态栏后顶部有灰条的问题解决
iOS11以上系统当启用沉浸式式状态栏后,webview默认会调整内容至安全区域之内,视觉效果如下图:
如果不需要自动调整可以在meta(name="viewport")节点的content属性值中添加viewport-fit=cover
状态栏大全-状态栏透明(沉浸式)、变色及全屏的区别
iOS平台5+SDK原生环境配置方法
Android平台设置沉浸式状态栏显示效果
XMLHttpRequest(跨域请求)问题汇总
服务器无法接收到提交的数据
- 确保手机网络畅通,能访问服务器地址(可用手机浏览器打开请求的网址)
- 确保提交的数据内容格式(XMLHttpRequest默认提交的content-type为“text/plain;charset=UTF-8”)
var xhr=new plus.net.XMLHttpRequest(); xhr.onreadystatechange=function(){ console.log('onreadystatechange: '+xhr.readyState); }; xhr.open( ‘POST’, ‘http://demo.dcloud.net.cn/test/xhr/’ ); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send('user=HBuilder&test=value');
XMLHttpRequest的setRequestHeader改不了contentype
http://ask.dcloud.net.cn/question/672
XMLHttpRequest的post请求时怎么传值?
http://ask.dcloud.net.cn/question/202
XMLHttpRequest在IOS中不可用?
服务器无法接收到提交的数据
- 确保手机网络畅通,能访问服务器地址(可用手机浏览器打开请求的网址)
- 确保提交的数据内容格式(XMLHttpRequest默认提交的content-type为“text/plain;charset=UTF-8”)
var xhr=new plus.net.XMLHttpRequest(); xhr.onreadystatechange=function(){ console.log('onreadystatechange: '+xhr.readyState); }; xhr.open( ‘POST’, ‘http://demo.dcloud.net.cn/test/xhr/’ ); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send('user=HBuilder&test=value');
XMLHttpRequest的setRequestHeader改不了contentype
http://ask.dcloud.net.cn/question/672
XMLHttpRequest的post请求时怎么传值?
http://ask.dcloud.net.cn/question/202
XMLHttpRequest在IOS中不可用?
http://ask.dcloud.net.cn/question/422
收起阅读 »【已过期】Uploader文件上传数据传输协议
此文档已过期,文件上传不支持断点续传功能,上传数据使用HTTP/HTTPS标准规范Multipart/form-data格式
技术规范
文件上传传输协议基于标准的http协议中的multipart/form-data格式,为支持断点续传功能,采用对HTTP协议扩展,规定单个文件上传的Range,用于保存上传的数据段位置信息。
文件上传业务需兼容https协议,可无缝切换到https传输通道。
文件上传业务流程

为了兼容各种服务器,5+ runtime需兼容两种模式,在连接不支持断点续传的服务器时采用非断点方式上传,在连接支持断点续传的服务器时采用断点模式分段提交数据。
文件删除传输协议
-
向服务器询问是否支持断点续传
该查询包括服务器是否支持扩展协议和任务上传的状态,每次任务启动时都要进行查询,如果服务器发送的格式错误认为不支持,直接使用标准HTTP协议传输。
上传数据格式(POST):
HTTP头
Content-Type:application/x-www-form-urlencoded
数据体
数据体格式为url参数对需要进行url编码,包括以下字段:
server:固定为字符串"uploader" ;
action:固定为字符串"query";
boundary:采用multipart/form-data格式的boundary值;
如:
server=uploader&action=query&boundary= ----WebKitFormBoundaryaXBIy1C8VXJFfgdS
Boundary 值为客户端提交的上传任务唯一标识,由客户端生成提交。 -
服务器返回断点续传信息
服务器下发数据为JSON格式,内容携带protocal、 support、file、data等字段,格式如下:
{
protocol: "uploder",
support: true,
boundary: "boundary",
file: [ { name: "headimage",
range: "0-102400"
}
],
data: [ { name: "name"
}
]
}
protocol 值为uploader可没有
support 值为Bool,必选 用来只是服务器是否支持此协议
boundary 值为boundary,必选 跟客户端上传的boundary一致
file值为file对象数组,关于file对象的约定,name为单个文件的唯一标识,值跟客户端上上传的字段名一致,必须包含range字段标识服务器已经接受的数据范围,其他属性不做要求 -
客户端向服务器提交上传数据
数据发送采用标准HTTP MIME封装格式的扩展Content-Type为multipart/form-data;boundary=%boundaryid%,其中boundaryid值用于标识上传任务,客户端需通过算法生成任务标识保证其唯一性。
为了支持上传文件的断点续传,在multipart/form-data格式的数据段中,需扩展Content- Disposition字段,添加range属性,其值用于表明当前传输的数据段,格式如下:
Content- Disposition: …; range=”start-end/totalsize”,示例如下:
Content- Disposition: form-data; name="file"; filename="image.jpg"; range=”102400-204800/456770”
若服务器不支持断点续传,则不传输range属性数据。
服务器在收到数据后根据Range进行文件组装,成功完整后返回200,客户端发送下一段数据。 -
服务器返回提交上传数据结果
服务器接收到上传数据后根据Range进行文件组装,操作成功后返回200,并在数据体中下发JSON数据,内容携带result字段,格式如下:
{
result: "OK",
code: %ErrorCode%,
message: "Error message"
}
result 值为上传数据的结果,上传成功固定值为"OK",上传失败固定值为"ERROR"。
code 值为可选数据,数字类型,通常在上传失败时用于保存错误代码,成功时其值为0,参考错误列表。
message 值为可选数据,通常在上传失败时用于保存错误提示信息。
服务器如果接收数据失败则http头中的,如4xx。
错误列表:错误代码 说明 0 Success 4001 File exceeded upload_max_filesize 4002 File exceeded max_file_size 4003 File only partially uploaded 4004 No file uploaded 4006 Cannot upload file: No temp directory specified 4007 Upload failed: Cannot write to disk 4008 File upload stopped by extension
示例
-
向服务器询问是否支持断点续传
POST /FileUploader/ HTTP/1.1
Host: www.baidu.com
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Accept-Language: en-us
Accept: /
Connection: keep-alive
User-Agent: MSC_Pandora/1.0 CFNetwork/609.1.4 Darwin/11.4.2
server=uploader&action=query&boundary=----WebKitFormBoundaryaXBIy1C8VXJFfgdS -
服务器返回断点续传信息
HTTP/1.1 200 Found
Date: Mon, 25 Mar 2013 03:00:35 GMT
Server: Apache
Location: http://www.baidu.com/search/error.html
Cache-Control: max-age=86400
Expires: Tue, 26 Mar 2013 03:00:35 GMT
Content-Length: 222
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
{protocol:”uploder”,support:true,boundary:”----WebKitFormBoundaryaXBIy1C8VXJFfgdS”, file:[{name:”headimage”,range:”0-102400”}],data:[{name:”name value”}]} -
客户端向服务器提交上传数据
POST /FileUploader/servlet/Uploader HTTP/1.1
Host: localhost:8080
Referer: http://localhost:8080/FileUploader/
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Length: 104010
Accept-Language: en-us
Origin: http://localhost:8080
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=D59492623EA81462A605B216B4A9E976
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B141
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
......JFIF.............XExif..MM.*...................i.........&.............................6...........5.......C.........................................
......QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE....
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="file"; filename="image.jpg"; range=”102400-204800/456770”
Content-Type: image/jpeg
......JFIF.............XExif..MM.*...................i.........&.............................6...........5.......C.........................................
....
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="submit"
......
------WebKitFormBoundaryaXBIy1C8VXJFfgdS--
- 服务器返回上传数据结果
HTTP/1.1 200 OK
Date: Mon, 25 Mar 2013 03:00:35 GMT
Server: Apache
Location: http://www.baidu.com/search/error.html
Cache-Control: max-age=86400
Expires: Tue, 26 Mar 2013 03:00:35 GMT
Content-Length: 222
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
{result:”OK”}
此文档已过期,文件上传不支持断点续传功能,上传数据使用HTTP/HTTPS标准规范Multipart/form-data格式
技术规范
文件上传传输协议基于标准的http协议中的multipart/form-data格式,为支持断点续传功能,采用对HTTP协议扩展,规定单个文件上传的Range,用于保存上传的数据段位置信息。
文件上传业务需兼容https协议,可无缝切换到https传输通道。
文件上传业务流程

为了兼容各种服务器,5+ runtime需兼容两种模式,在连接不支持断点续传的服务器时采用非断点方式上传,在连接支持断点续传的服务器时采用断点模式分段提交数据。
文件删除传输协议
-
向服务器询问是否支持断点续传
该查询包括服务器是否支持扩展协议和任务上传的状态,每次任务启动时都要进行查询,如果服务器发送的格式错误认为不支持,直接使用标准HTTP协议传输。
上传数据格式(POST):
HTTP头
Content-Type:application/x-www-form-urlencoded
数据体
数据体格式为url参数对需要进行url编码,包括以下字段:
server:固定为字符串"uploader" ;
action:固定为字符串"query";
boundary:采用multipart/form-data格式的boundary值;
如:
server=uploader&action=query&boundary= ----WebKitFormBoundaryaXBIy1C8VXJFfgdS
Boundary 值为客户端提交的上传任务唯一标识,由客户端生成提交。 -
服务器返回断点续传信息
服务器下发数据为JSON格式,内容携带protocal、 support、file、data等字段,格式如下:
{
protocol: "uploder",
support: true,
boundary: "boundary",
file: [ { name: "headimage",
range: "0-102400"
}
],
data: [ { name: "name"
}
]
}
protocol 值为uploader可没有
support 值为Bool,必选 用来只是服务器是否支持此协议
boundary 值为boundary,必选 跟客户端上传的boundary一致
file值为file对象数组,关于file对象的约定,name为单个文件的唯一标识,值跟客户端上上传的字段名一致,必须包含range字段标识服务器已经接受的数据范围,其他属性不做要求 -
客户端向服务器提交上传数据
数据发送采用标准HTTP MIME封装格式的扩展Content-Type为multipart/form-data;boundary=%boundaryid%,其中boundaryid值用于标识上传任务,客户端需通过算法生成任务标识保证其唯一性。
为了支持上传文件的断点续传,在multipart/form-data格式的数据段中,需扩展Content- Disposition字段,添加range属性,其值用于表明当前传输的数据段,格式如下:
Content- Disposition: …; range=”start-end/totalsize”,示例如下:
Content- Disposition: form-data; name="file"; filename="image.jpg"; range=”102400-204800/456770”
若服务器不支持断点续传,则不传输range属性数据。
服务器在收到数据后根据Range进行文件组装,成功完整后返回200,客户端发送下一段数据。 -
服务器返回提交上传数据结果
服务器接收到上传数据后根据Range进行文件组装,操作成功后返回200,并在数据体中下发JSON数据,内容携带result字段,格式如下:
{
result: "OK",
code: %ErrorCode%,
message: "Error message"
}
result 值为上传数据的结果,上传成功固定值为"OK",上传失败固定值为"ERROR"。
code 值为可选数据,数字类型,通常在上传失败时用于保存错误代码,成功时其值为0,参考错误列表。
message 值为可选数据,通常在上传失败时用于保存错误提示信息。
服务器如果接收数据失败则http头中的,如4xx。
错误列表:错误代码 说明 0 Success 4001 File exceeded upload_max_filesize 4002 File exceeded max_file_size 4003 File only partially uploaded 4004 No file uploaded 4006 Cannot upload file: No temp directory specified 4007 Upload failed: Cannot write to disk 4008 File upload stopped by extension
示例
-
向服务器询问是否支持断点续传
POST /FileUploader/ HTTP/1.1
Host: www.baidu.com
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Accept-Language: en-us
Accept: /
Connection: keep-alive
User-Agent: MSC_Pandora/1.0 CFNetwork/609.1.4 Darwin/11.4.2
server=uploader&action=query&boundary=----WebKitFormBoundaryaXBIy1C8VXJFfgdS -
服务器返回断点续传信息
HTTP/1.1 200 Found
Date: Mon, 25 Mar 2013 03:00:35 GMT
Server: Apache
Location: http://www.baidu.com/search/error.html
Cache-Control: max-age=86400
Expires: Tue, 26 Mar 2013 03:00:35 GMT
Content-Length: 222
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
{protocol:”uploder”,support:true,boundary:”----WebKitFormBoundaryaXBIy1C8VXJFfgdS”, file:[{name:”headimage”,range:”0-102400”}],data:[{name:”name value”}]} -
客户端向服务器提交上传数据
POST /FileUploader/servlet/Uploader HTTP/1.1
Host: localhost:8080
Referer: http://localhost:8080/FileUploader/
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Length: 104010
Accept-Language: en-us
Origin: http://localhost:8080
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=D59492623EA81462A605B216B4A9E976
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B141
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
......JFIF.............XExif..MM.*...................i.........&.............................6...........5.......C.........................................
......QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE..QE....
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="file"; filename="image.jpg"; range=”102400-204800/456770”
Content-Type: image/jpeg
......JFIF.............XExif..MM.*...................i.........&.............................6...........5.......C.........................................
....
------WebKitFormBoundaryaXBIy1C8VXJFfgdS
Content-Disposition: form-data; name="submit"
......
------WebKitFormBoundaryaXBIy1C8VXJFfgdS--
- 服务器返回上传数据结果
HTTP/1.1 200 OK
Date: Mon, 25 Mar 2013 03:00:35 GMT
Server: Apache
Location: http://www.baidu.com/search/error.html
Cache-Control: max-age=86400
Expires: Tue, 26 Mar 2013 03:00:35 GMT
Content-Length: 222
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
{result:”OK”}
Uploader(文件上传)问题汇总
文件上传数据传输协议
Uploader上传使用标准HTTP/HTTPS的POST方式提交数据,数据格式符合Multipart/form-data规范,即rfc1867(Form-based File Upload in HTML)协议
文件上传服务器代码如何实现
http://ask.dcloud.net.cn/question/722
以上为5+App的上传,uni-app的上传参考:https://uniapp.dcloud.io/api/request/network-file?id=uploadfile
另外,uniCloud提供了免费的cdn,建议上传到uniCloud,详见:https://uniapp.dcloud.io/uniCloud/storage
文件上传是否支持断点续传
目前不支持断点续传
文件上传数据传输协议
Uploader上传使用标准HTTP/HTTPS的POST方式提交数据,数据格式符合Multipart/form-data规范,即rfc1867(Form-based File Upload in HTML)协议
文件上传服务器代码如何实现
http://ask.dcloud.net.cn/question/722
以上为5+App的上传,uni-app的上传参考:https://uniapp.dcloud.io/api/request/network-file?id=uploadfile
另外,uniCloud提供了免费的cdn,建议上传到uniCloud,详见:https://uniapp.dcloud.io/uniCloud/storage
文件上传是否支持断点续传
目前不支持断点续传
收起阅读 »Native.js示例汇总
Native.js虽然强大和开放,但很多web开发者因为不熟悉原生API而难以独立完成。
这篇帖子的目的就是汇总各种写好的NJS代码,方便web开发者。
众人拾柴火焰高,有能力的开发者多多提交NJS代码,大家都会给你点赞的,我们也会为每位共享NJS代码的朋友送上200积分。
Native.js在涉及js层和原生层频繁交互时会有性能问题,js和原生的数据类型也无法全部拉齐。但Native.js是5+app和uni-app通用。如果仅是uni-app,其实推荐更强大的uts,详见
Android平台
监听手机锁屏,解锁,开屏
http://ask.dcloud.net.cn/article/35205
直接拨打电话
http://ask.dcloud.net.cn/question/4035
将程序切换到后台
http://ask.dcloud.net.cn/question/2484
强制弹出软键盘
http://ask.dcloud.net.cn/question/2324
获取安卓设备device.uuid
http://ask.dcloud.net.cn/question/3510
获取内存及CPU信息
http://ask.dcloud.net.cn/question/2202
开启关闭蓝牙
http://ask.dcloud.net.cn/question/4720
监听蓝牙开关状态
http://ask.dcloud.net.cn/article/274
获取蓝牙设备列表
http://ask.dcloud.net.cn/question/8265
蓝牙连接票据打印机完整代码
http://ask.dcloud.net.cn/article/643
NFC数据读取
http://ask.dcloud.net.cn/question/6726
截屏
http://ask.dcloud.net.cn/question/5344
获取MAC地址
http://ask.dcloud.net.cn/question/1511
获取设备当前网速
http://ask.dcloud.net.cn/article/773
打开网络设置
http://ask.dcloud.net.cn/question/1475
打开各种系统设置界面
http://ask.dcloud.net.cn/question/14732
获取WIFI列表
http://ask.dcloud.net.cn/question/12113
调用系统控件播放视频
http://ask.dcloud.net.cn/question/614
调用os通讯录选择控件
http://ask.dcloud.net.cn/question/5783
原生日历提醒插入
http://ask.dcloud.net.cn/article/215
AlarmManager闹钟定时任务
https://ask.dcloud.net.cn/article/36125
调用系统控件裁剪图片
http://ask.dcloud.net.cn/question/8314
复制内容到系统粘贴板
http://ask.dcloud.net.cn/question/2034
调用讯飞的文字转语音功能(TTS)
http://ask.dcloud.net.cn/question/6473
调用其它Activity后通过startActivityForResult获取返回结果
http://ask.dcloud.net.cn/question/5783
接收系统广播消息,如监听安装卸载apk的事件
http://ask.dcloud.net.cn/article/222
判断app是否安装
http://ask.dcloud.net.cn/question/7604
以监听手机飞行模式开关为例说明如何使用Native.js进行BroadcastReceiver广播
http://ask.dcloud.net.cn/question/7661
常驻Android通知栏,不用个推实现本地消息推送(Local Notification)
http://ask.dcloud.net.cn/question/2464
调用原生的socket连接
http://ask.dcloud.net.cn/question/60
启动一个原生service
http://ask.dcloud.net.cn/question/433
基于native.js的文件系统管理功能实现
http://ask.dcloud.net.cn/article/809
打开闪光灯
http://ask.dcloud.net.cn/question/19379
停止、开启个推推送功能
var pushManager = plus.android.importClass("com.igexin.sdk.PushManager");
var context = plus.android.runtimeMainActivity();
function enable() {
pushManager.getInstance().turnOnPush(context);
}
function disable() {
pushManager.getInstance().turnOffPush(context);
}
感谢yeahcheung分享
利用native.js获取手机gps是否开启
http://ask.dcloud.net.cn/question/11890
通过native.js设置系统墙纸
http://ask.dcloud.net.cn/article/651
监听短信验证码
http://ask.dcloud.net.cn/article/676
遍历短信内容
https://ask.dcloud.net.cn/article/12934
限制手机录像时间
http://ask.dcloud.net.cn/question/45756
Android监听电话呼入呼出
http://ask.dcloud.net.cn/article/1006
Android6以上动态权限申请
https://ask.dcloud.net.cn/article/35091
通知栏下载进度条
https://ask.dcloud.net.cn/article/503
打开应用市场
https://ask.dcloud.net.cn/article/12753
检查手机是否被root
https://ask.dcloud.net.cn/article/36471
iOS平台
跳转系统设置页面
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
如何判断系统功能权限是否开启(比如定位、推送)及提示用户开启权限
https://ask.dcloud.net.cn/article/35915
获取包名
var NSBundle = plus.ios.importClass('NSBundle');
var bundle = NSBundle.mainBundle();
console.log(bundle.bundleIdentifier());
plus.ios.deleteObject(bundle);
获取设备名
http://ask.dcloud.net.cn/question/14691
测试是否安装某应用
http://ask.dcloud.net.cn/question/14430
调用iOS打印API
http://ask.dcloud.net.cn/question/4226
通过native.js登入game center
见Hello H5+里Native.js部分演示及源码。
或在这里搜索“game center”,http://ask.dcloud.net.cn/docs/#http://ask.dcloud.net.cn/article/88
设置获取内容到系统粘贴板
http://ask.dcloud.net.cn/question/3720
打开页面默认弹出键盘
http://ask.dcloud.net.cn/question/2324
播放提示音
http://ask.dcloud.net.cn/question/3962
调用ios的文字转语音(TTS)
http://ask.dcloud.net.cn/question/4175
把base64数据保存为图片
http://ask.dcloud.net.cn/question/6190
设置webview滑动减速度
var webview = plus.ios.currentWebview();
var scrollView = webview.plusGetAttribute("scrollView");
scrollView.plusSetAttribute("decelerationRate:",0.99);
打开应用市场
https://ask.dcloud.net.cn/article/12753
ios获取系统的时区id
var NSTimeZone = plus.ios.importClass("NSTimeZone");
var sys = NSTimeZone.systemTimeZone();
console.log(sys.plusGetAttribute("name"));
状态栏显示网络请求雪花
var UIApplication = plus.ios.import("UIApplication");
var sharedApplication = UIApplication.sharedApplication();
sharedApplication.setNetworkActivityIndicatorVisible(true);
plus.ios.deleteObject(sharedApplication);
获取GPS授权状态
var CLLocationManager = plus.ios.import("CLLocationManager");
var authorizationStatus = CLLocationManager.authorizationStatus();
switch(authorizationStatus) {
case 0:
/// User has not yet made a choice with regards to this application
break;
case 1:
// This application is not authorized to use location services. Due
// to active restrictions on location services, the user cannot change
// this status, and may not have personally denied authorization
break;
case 2:
// User has explicitly denied authorization for this application, or
// location services are disabled in Settings.
break;
case 3:
// User has granted authorization to use their location at any time,
// including monitoring for regions, visits, or significant location changes.
break;
case 4:
// User has granted authorization to use their location only when your app
// is visible to them (it will be made visible to them if you continue to
// receive location updates while in the background). Authorization to use
// launch APIs has not been granted.
break;
case 5:
// This value is deprecated, but was equivalent to the new -Always value.
break;
defalut:
break;
}
获取手机存储空间
var BundleClass = plus.ios.importClass("NSBundle");
var BundleObj = BundleClass.mainBundle();
var filenamagerobj = plus.ios.newObject("NSFileManager");
var FileAttr = plus.ios.invoke(filenamagerobj,"attributesOfFileSystemForPath:error:",BundleObj.bundlePath(),null);
// NSFileSystemFreeSize 参数获取剩余空间
// NSFileSystemSize 获取手机总存储空间
var freeSpace = plus.ios.invoke(FileAttr,"objectForKey:","NSFileSystemFreeSize");
var numberFormatterObj = plus.ios.newObject("NSNumberFormatter");
var FreeSpaceStr = plus.ios.invoke(numberFormatterObj,"stringFromNumber:",freeSpace);
var freeSpace = FreeSpaceStr / 1024/1024/1024;
打开/关闭手机的闪光灯
function turnonLight(isOn) {
if(plus.os.name == "iOS") {
var avcaptClass = plus.ios.importClass("AVCaptureDevice");
if(avcaptClass) {
var device = avcaptClass.defaultDeviceWithMediaType("vide");
plus.ios.invoke(device, "lockForConfiguration:", null);
if(isOn) {
plus.ios.invoke(device, "setTorchMode:", 1);
plus.ios.invoke(device, "setFlashMode:", 1);
} else {
plus.ios.invoke(device, "setTorchMode:", 0);
plus.ios.invoke(device, "setFlashMode:", 0);
}
plus.ios.invoke(device, "unlockForConfiguration");
}
}
};
显示应用内的ViewController
// NewViewController为应用内创建的原生的ViewController类名,所调用页面的内容需要在原生代码中完成
var newVCobj = plus.ios.newObject("NewViewController");
var UIApplicationClass = plus.ios.importClass("UIApplication");
var UIAppObj = UIApplicationClass.sharedApplication();
var del = plus.ios.invoke(UIAppObj,"delegate");
// 如果当前应用delegate对象包含UIWindow对象并且变量名命名为“window”可以这么写,
// 否则需要根据实际代码情况修改
// 应用的delegate对象也可以添加一个返回UIViewController的方法
var appWindowObj = plus.ios.invoke(del,"window");
var appRootController = plus.ios.invoke(appWindowObj,"rootViewController");
plus.ios.invoke(appRootController,"presentViewController:animated:completion:",newVCobj,"YES",null);
看完这些例子,是不是觉得JS特别强大?
赶快拿去用起来吧!
Native.js虽然强大和开放,但很多web开发者因为不熟悉原生API而难以独立完成。
这篇帖子的目的就是汇总各种写好的NJS代码,方便web开发者。
众人拾柴火焰高,有能力的开发者多多提交NJS代码,大家都会给你点赞的,我们也会为每位共享NJS代码的朋友送上200积分。
Native.js在涉及js层和原生层频繁交互时会有性能问题,js和原生的数据类型也无法全部拉齐。但Native.js是5+app和uni-app通用。如果仅是uni-app,其实推荐更强大的uts,详见
Android平台
监听手机锁屏,解锁,开屏
http://ask.dcloud.net.cn/article/35205
直接拨打电话
http://ask.dcloud.net.cn/question/4035
将程序切换到后台
http://ask.dcloud.net.cn/question/2484
强制弹出软键盘
http://ask.dcloud.net.cn/question/2324
获取安卓设备device.uuid
http://ask.dcloud.net.cn/question/3510
获取内存及CPU信息
http://ask.dcloud.net.cn/question/2202
开启关闭蓝牙
http://ask.dcloud.net.cn/question/4720
监听蓝牙开关状态
http://ask.dcloud.net.cn/article/274
获取蓝牙设备列表
http://ask.dcloud.net.cn/question/8265
蓝牙连接票据打印机完整代码
http://ask.dcloud.net.cn/article/643
NFC数据读取
http://ask.dcloud.net.cn/question/6726
截屏
http://ask.dcloud.net.cn/question/5344
获取MAC地址
http://ask.dcloud.net.cn/question/1511
获取设备当前网速
http://ask.dcloud.net.cn/article/773
打开网络设置
http://ask.dcloud.net.cn/question/1475
打开各种系统设置界面
http://ask.dcloud.net.cn/question/14732
获取WIFI列表
http://ask.dcloud.net.cn/question/12113
调用系统控件播放视频
http://ask.dcloud.net.cn/question/614
调用os通讯录选择控件
http://ask.dcloud.net.cn/question/5783
原生日历提醒插入
http://ask.dcloud.net.cn/article/215
AlarmManager闹钟定时任务
https://ask.dcloud.net.cn/article/36125
调用系统控件裁剪图片
http://ask.dcloud.net.cn/question/8314
复制内容到系统粘贴板
http://ask.dcloud.net.cn/question/2034
调用讯飞的文字转语音功能(TTS)
http://ask.dcloud.net.cn/question/6473
调用其它Activity后通过startActivityForResult获取返回结果
http://ask.dcloud.net.cn/question/5783
接收系统广播消息,如监听安装卸载apk的事件
http://ask.dcloud.net.cn/article/222
判断app是否安装
http://ask.dcloud.net.cn/question/7604
以监听手机飞行模式开关为例说明如何使用Native.js进行BroadcastReceiver广播
http://ask.dcloud.net.cn/question/7661
常驻Android通知栏,不用个推实现本地消息推送(Local Notification)
http://ask.dcloud.net.cn/question/2464
调用原生的socket连接
http://ask.dcloud.net.cn/question/60
启动一个原生service
http://ask.dcloud.net.cn/question/433
基于native.js的文件系统管理功能实现
http://ask.dcloud.net.cn/article/809
打开闪光灯
http://ask.dcloud.net.cn/question/19379
停止、开启个推推送功能
var pushManager = plus.android.importClass("com.igexin.sdk.PushManager");
var context = plus.android.runtimeMainActivity();
function enable() {
pushManager.getInstance().turnOnPush(context);
}
function disable() {
pushManager.getInstance().turnOffPush(context);
}
感谢yeahcheung分享
利用native.js获取手机gps是否开启
http://ask.dcloud.net.cn/question/11890
通过native.js设置系统墙纸
http://ask.dcloud.net.cn/article/651
监听短信验证码
http://ask.dcloud.net.cn/article/676
遍历短信内容
https://ask.dcloud.net.cn/article/12934
限制手机录像时间
http://ask.dcloud.net.cn/question/45756
Android监听电话呼入呼出
http://ask.dcloud.net.cn/article/1006
Android6以上动态权限申请
https://ask.dcloud.net.cn/article/35091
通知栏下载进度条
https://ask.dcloud.net.cn/article/503
打开应用市场
https://ask.dcloud.net.cn/article/12753
检查手机是否被root
https://ask.dcloud.net.cn/article/36471
iOS平台
跳转系统设置页面
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
如何判断系统功能权限是否开启(比如定位、推送)及提示用户开启权限
https://ask.dcloud.net.cn/article/35915
获取包名
var NSBundle = plus.ios.importClass('NSBundle');
var bundle = NSBundle.mainBundle();
console.log(bundle.bundleIdentifier());
plus.ios.deleteObject(bundle);
获取设备名
http://ask.dcloud.net.cn/question/14691
测试是否安装某应用
http://ask.dcloud.net.cn/question/14430
调用iOS打印API
http://ask.dcloud.net.cn/question/4226
通过native.js登入game center
见Hello H5+里Native.js部分演示及源码。
或在这里搜索“game center”,http://ask.dcloud.net.cn/docs/#http://ask.dcloud.net.cn/article/88
设置获取内容到系统粘贴板
http://ask.dcloud.net.cn/question/3720
打开页面默认弹出键盘
http://ask.dcloud.net.cn/question/2324
播放提示音
http://ask.dcloud.net.cn/question/3962
调用ios的文字转语音(TTS)
http://ask.dcloud.net.cn/question/4175
把base64数据保存为图片
http://ask.dcloud.net.cn/question/6190
设置webview滑动减速度
var webview = plus.ios.currentWebview();
var scrollView = webview.plusGetAttribute("scrollView");
scrollView.plusSetAttribute("decelerationRate:",0.99);
打开应用市场
https://ask.dcloud.net.cn/article/12753
ios获取系统的时区id
var NSTimeZone = plus.ios.importClass("NSTimeZone");
var sys = NSTimeZone.systemTimeZone();
console.log(sys.plusGetAttribute("name"));
状态栏显示网络请求雪花
var UIApplication = plus.ios.import("UIApplication");
var sharedApplication = UIApplication.sharedApplication();
sharedApplication.setNetworkActivityIndicatorVisible(true);
plus.ios.deleteObject(sharedApplication);
获取GPS授权状态
var CLLocationManager = plus.ios.import("CLLocationManager");
var authorizationStatus = CLLocationManager.authorizationStatus();
switch(authorizationStatus) {
case 0:
/// User has not yet made a choice with regards to this application
break;
case 1:
// This application is not authorized to use location services. Due
// to active restrictions on location services, the user cannot change
// this status, and may not have personally denied authorization
break;
case 2:
// User has explicitly denied authorization for this application, or
// location services are disabled in Settings.
break;
case 3:
// User has granted authorization to use their location at any time,
// including monitoring for regions, visits, or significant location changes.
break;
case 4:
// User has granted authorization to use their location only when your app
// is visible to them (it will be made visible to them if you continue to
// receive location updates while in the background). Authorization to use
// launch APIs has not been granted.
break;
case 5:
// This value is deprecated, but was equivalent to the new -Always value.
break;
defalut:
break;
}
获取手机存储空间
var BundleClass = plus.ios.importClass("NSBundle");
var BundleObj = BundleClass.mainBundle();
var filenamagerobj = plus.ios.newObject("NSFileManager");
var FileAttr = plus.ios.invoke(filenamagerobj,"attributesOfFileSystemForPath:error:",BundleObj.bundlePath(),null);
// NSFileSystemFreeSize 参数获取剩余空间
// NSFileSystemSize 获取手机总存储空间
var freeSpace = plus.ios.invoke(FileAttr,"objectForKey:","NSFileSystemFreeSize");
var numberFormatterObj = plus.ios.newObject("NSNumberFormatter");
var FreeSpaceStr = plus.ios.invoke(numberFormatterObj,"stringFromNumber:",freeSpace);
var freeSpace = FreeSpaceStr / 1024/1024/1024;
打开/关闭手机的闪光灯
function turnonLight(isOn) {
if(plus.os.name == "iOS") {
var avcaptClass = plus.ios.importClass("AVCaptureDevice");
if(avcaptClass) {
var device = avcaptClass.defaultDeviceWithMediaType("vide");
plus.ios.invoke(device, "lockForConfiguration:", null);
if(isOn) {
plus.ios.invoke(device, "setTorchMode:", 1);
plus.ios.invoke(device, "setFlashMode:", 1);
} else {
plus.ios.invoke(device, "setTorchMode:", 0);
plus.ios.invoke(device, "setFlashMode:", 0);
}
plus.ios.invoke(device, "unlockForConfiguration");
}
}
};
显示应用内的ViewController
// NewViewController为应用内创建的原生的ViewController类名,所调用页面的内容需要在原生代码中完成
var newVCobj = plus.ios.newObject("NewViewController");
var UIApplicationClass = plus.ios.importClass("UIApplication");
var UIAppObj = UIApplicationClass.sharedApplication();
var del = plus.ios.invoke(UIAppObj,"delegate");
// 如果当前应用delegate对象包含UIWindow对象并且变量名命名为“window”可以这么写,
// 否则需要根据实际代码情况修改
// 应用的delegate对象也可以添加一个返回UIViewController的方法
var appWindowObj = plus.ios.invoke(del,"window");
var appRootController = plus.ios.invoke(appWindowObj,"rootViewController");
plus.ios.invoke(appRootController,"presentViewController:animated:completion:",newVCobj,"YES",null);
看完这些例子,是不是觉得JS特别强大?
赶快拿去用起来吧!
mui适用场景说明,能不能在普通浏览器里使用,能否用于wap网站
mui适用场景说明
===
为解决HTML5在低端Android机上的性能缺陷,mui引入了原生加速,其中最关键的就是webview控件,因此mui若要发挥其全部能力,需和5+ App配合适用,若脱离5+ App,mui功能会受限,主要涉及三个部分:
webview窗口相关
涉及webview的,除了5+App,其它所有手机浏览器及PC浏览器均无法使用,涉及功能点包括:
- webview模式窗体动画
- 创建子窗口(除了为解决区域滚动的常见双webview场景,还涉及webview模式的选项卡等多webview场景)
- webview模式的侧滑菜单(也有div方式侧滑菜单)
- webview模式的tab选项卡(也有div方式选项卡)
- nativeUI,如原生的警告框、确认框、popover、actionsheet、toast。这些也有HTML5的实现。
- 预加载
- 自定义事件
第三方扩展插件
涉及webview的,除了5+App,其它所有手机浏览器及PC浏览器均无法使用,目前主要包括:语音输入;
Touch事件相关(注意pc浏览器没有touch事件)
Touch事件相关的,手机端浏览器均可使用、pc端chrome模拟手机浏览器也可以正常使用。
但普通PC端浏览器因为没有touch事件,可以显示控件但滑动操作功能会受限;涉及功能点包括:
- 手势事件
- mui封装的tap相关处理业务:折叠面板、二级列表、二级选项卡;
- mui封装的swipe、drag相关处理业务:图片轮播、可左右滑动的图文表格、可左右滑动的9宫格、滑动触发列表项菜单、可拖动式侧滑菜单、下拉刷新和上拉加载、可拖动式选项卡
【备注】:在PC端,大家将tap替换成click,将HTML5默认的Drag事件替换mui 的swipe和drag,就可以解决如上两个问题。
除上述列出的功能点,其它mui功能,均可以在其它手机浏览器及PC服务端使用,所有CSS均不受影响。
很多开发者使用mui开发了web app,这里有一些案例:
搜达足球
财经早报
天行者户外
华职人才网
若通过PC端chrome模拟手机浏览器访问hello mui,只能看到首页标题栏,看不到列表,因为列表是作为子webview页面加载到首页的,如无法显示。
mui适用场景说明
===
为解决HTML5在低端Android机上的性能缺陷,mui引入了原生加速,其中最关键的就是webview控件,因此mui若要发挥其全部能力,需和5+ App配合适用,若脱离5+ App,mui功能会受限,主要涉及三个部分:
webview窗口相关
涉及webview的,除了5+App,其它所有手机浏览器及PC浏览器均无法使用,涉及功能点包括:
- webview模式窗体动画
- 创建子窗口(除了为解决区域滚动的常见双webview场景,还涉及webview模式的选项卡等多webview场景)
- webview模式的侧滑菜单(也有div方式侧滑菜单)
- webview模式的tab选项卡(也有div方式选项卡)
- nativeUI,如原生的警告框、确认框、popover、actionsheet、toast。这些也有HTML5的实现。
- 预加载
- 自定义事件
第三方扩展插件
涉及webview的,除了5+App,其它所有手机浏览器及PC浏览器均无法使用,目前主要包括:语音输入;
Touch事件相关(注意pc浏览器没有touch事件)
Touch事件相关的,手机端浏览器均可使用、pc端chrome模拟手机浏览器也可以正常使用。
但普通PC端浏览器因为没有touch事件,可以显示控件但滑动操作功能会受限;涉及功能点包括:
- 手势事件
- mui封装的tap相关处理业务:折叠面板、二级列表、二级选项卡;
- mui封装的swipe、drag相关处理业务:图片轮播、可左右滑动的图文表格、可左右滑动的9宫格、滑动触发列表项菜单、可拖动式侧滑菜单、下拉刷新和上拉加载、可拖动式选项卡
【备注】:在PC端,大家将tap替换成click,将HTML5默认的Drag事件替换mui 的swipe和drag,就可以解决如上两个问题。
除上述列出的功能点,其它mui功能,均可以在其它手机浏览器及PC服务端使用,所有CSS均不受影响。
很多开发者使用mui开发了web app,这里有一些案例:
搜达足球
财经早报
天行者户外
华职人才网
若通过PC端chrome模拟手机浏览器访问hello mui,只能看到首页标题栏,看不到列表,因为列表是作为子webview页面加载到首页的,如无法显示。
收起阅读 »App云端打包失败常见问题汇总
用户在使用在线打包功能打包时可能遇到打包失败的问题,本文主要描述集中常见的问题用户可以对照排除打包常见的错误。
Android云端打包
错误原因:图片格式不对,应用图标和启动图片都要求png格式,其它格式(如jpg)会报错。
解决方法:请检查应用的图标是否有格式问题,严格按照指定的尺寸使用png格式提交打包。
图标文件和启动图片都需要png格式的图片,用户可以根据HBuilder提示添加指定尺寸的图片或者通过修改manifest文件修改图片的因引用,具体修改方式可参考
务必注意不能把jpg等文件改名为png来使用。
打包后如果图标不变化,可能是因为缓存,重启下手机试试。
错误原因:应用名称中包含特殊字符如“@”等
解决方法:修改应用名称,去掉特殊字符
错误原因:打包后APP空白
解决方法:(1)请检查应用的appid是否被修改,
注意此appid并非是包名,如果修改了,可以新建一个app项目复制其appid即可
(2)由于特殊字符导致解析失败
检查文件夹是否有特殊字符ios云端打包
用户在选择“appstore专用”选项打非越狱包时可能遇到如下问题。
1. 配置的profile(.mobileprovision)文件不正确
错误日志
Error reading S/MIME message
64601:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:/SourceCache/OpenSSL098/OpenSSL098-52.30.1/src/crypto/asn1/asn1_lib.c:153:
BuildConfigure Failed 31013 mobileprovision 不合法
解决方法:
请参考http://ask.dcloud.net.cn/article/152教程生成正确的profile(.mobileprovision)文件
2. 配置的证书(.p12)文件无效或者输入的证书密码错误
/usr/bin/security delete-certificate -c ""
Unable to delete certificate matching ""
BuildConfigure Failed 31011 无法获取p12证书的Team标识
解决方法:
这是因为p12文件中没有包含有效的证书内容,可以双击导入到系统证书库中,如果能正确导入则说明证书有效,Window系统会提示“指定的文件为空”。

用户打包是需要保证红框内的证书和绿框内密码相匹配,否则打包会失败
请参考http://ask.dcloud.net.cn/article/152教程导出正确的私钥(.p12)文件
3. 配置的APPID(bundle identifier)与profile(.mobileprovision)文件中包含的不一致
BuildConfigure Failed 31015 编译错误
xcode build 开始
----------------------------------------------------------------------
Check dependencies
Code Sign error: Provisioning profile does not match bundle identifier: The provisioning profile specified in your build settings (“TTTTTT”) has an AppID of “yy.yyy.YYYYYY” which does not match your bundle identifier “xx.xxx.XXXXXX”.
CodeSign error: code signing is required for product type 'Application' in SDK 'iOS 8.1'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
解决方法:
修改打包应用的APPID和profile文件一致即可

用户要保证提交的profile文件指定的appid和红框内的appid保持一致否则打包会失败
其中xx.xxx.XXXXXX为打包时配置的,而yy.yyy.YYYYYY为profile(.mobileprovision)文件中包含的。
4. 配置的证书(.p12)与profile(.mobileprovision)文件不区配
BuildConfigure Failed 31015 编译错误
xcode build 开始
----------------------------------------------------------------------
Check dependencies
Code Sign error: No codesigning identities found: No codesigning identities (i.e. certificate and private key pairs) that match the provisioning profile specified in your build settings (“TTTTTT”) were found.
CodeSign error: code signing is required for product type 'Application' in SDK 'iOS 8.4'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
以及:
/usr/bin/codesign --force --sign 128F9389E0B05671B3334551D3E46A04FDD716B2 --resource-rules=安装包制作目录build/Release-iphoneos/DCloud_Pandora.app/ResourceRules.plist --entitlements 安装包制作目录build/Pandora.build/Release-iphoneos/Pandora.build/DCloud_Pandora.app.xcent 安装包制作目录build/Release-iphoneos/DCloud_Pandora.app
Warning: --resource-rules has been deprecated in Mac OS X >= 10.10!
128F9389E0B05671B3334551D3E46A04FDD716B2: no identity found
Command /usr/bin/codesign failed with exit code 1
解决方法:
请参考http://ask.dcloud.net.cn/article/152教程导出正确的私钥(.p12)文件
5. 提示doesn't support the Push Notifications capability错误
BuildConfigure Failed 31015 编译错误
xcode build 开始
// ...
=== BUILD TARGET Pandora OF PROJECT Pandora WITH THE DEFAULT CONFIGURATION (Release) ===
Check dependencies
Provisioning profile "XXXXXXXX" doesn't support the Push Notifications capability.
Provisioning profile "XXXXXXXX" doesn't include the aps-environment entitlement.
Code signing is required for product type 'Application' in SDK 'iOS 10.0'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
解决方法:
请参考http://ask.dcloud.net.cn/article/1088
如用户遇到打包问题按照以上方法无法排除请联系管理员
用户在使用在线打包功能打包时可能遇到打包失败的问题,本文主要描述集中常见的问题用户可以对照排除打包常见的错误。
Android云端打包
错误原因:图片格式不对,应用图标和启动图片都要求png格式,其它格式(如jpg)会报错。
解决方法:请检查应用的图标是否有格式问题,严格按照指定的尺寸使用png格式提交打包。
图标文件和启动图片都需要png格式的图片,用户可以根据HBuilder提示添加指定尺寸的图片或者通过修改manifest文件修改图片的因引用,具体修改方式可参考
务必注意不能把jpg等文件改名为png来使用。
打包后如果图标不变化,可能是因为缓存,重启下手机试试。
错误原因:应用名称中包含特殊字符如“@”等
解决方法:修改应用名称,去掉特殊字符
错误原因:打包后APP空白
解决方法:(1)请检查应用的appid是否被修改,
注意此appid并非是包名,如果修改了,可以新建一个app项目复制其appid即可
(2)由于特殊字符导致解析失败
检查文件夹是否有特殊字符ios云端打包
用户在选择“appstore专用”选项打非越狱包时可能遇到如下问题。
1. 配置的profile(.mobileprovision)文件不正确
错误日志
Error reading S/MIME message
64601:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:/SourceCache/OpenSSL098/OpenSSL098-52.30.1/src/crypto/asn1/asn1_lib.c:153:
BuildConfigure Failed 31013 mobileprovision 不合法
解决方法:
请参考http://ask.dcloud.net.cn/article/152教程生成正确的profile(.mobileprovision)文件
2. 配置的证书(.p12)文件无效或者输入的证书密码错误
/usr/bin/security delete-certificate -c ""
Unable to delete certificate matching ""
BuildConfigure Failed 31011 无法获取p12证书的Team标识
解决方法:
这是因为p12文件中没有包含有效的证书内容,可以双击导入到系统证书库中,如果能正确导入则说明证书有效,Window系统会提示“指定的文件为空”。

用户打包是需要保证红框内的证书和绿框内密码相匹配,否则打包会失败
请参考http://ask.dcloud.net.cn/article/152教程导出正确的私钥(.p12)文件
3. 配置的APPID(bundle identifier)与profile(.mobileprovision)文件中包含的不一致
BuildConfigure Failed 31015 编译错误
xcode build 开始
----------------------------------------------------------------------
Check dependencies
Code Sign error: Provisioning profile does not match bundle identifier: The provisioning profile specified in your build settings (“TTTTTT”) has an AppID of “yy.yyy.YYYYYY” which does not match your bundle identifier “xx.xxx.XXXXXX”.
CodeSign error: code signing is required for product type 'Application' in SDK 'iOS 8.1'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
解决方法:
修改打包应用的APPID和profile文件一致即可

用户要保证提交的profile文件指定的appid和红框内的appid保持一致否则打包会失败
其中xx.xxx.XXXXXX为打包时配置的,而yy.yyy.YYYYYY为profile(.mobileprovision)文件中包含的。
4. 配置的证书(.p12)与profile(.mobileprovision)文件不区配
BuildConfigure Failed 31015 编译错误
xcode build 开始
----------------------------------------------------------------------
Check dependencies
Code Sign error: No codesigning identities found: No codesigning identities (i.e. certificate and private key pairs) that match the provisioning profile specified in your build settings (“TTTTTT”) were found.
CodeSign error: code signing is required for product type 'Application' in SDK 'iOS 8.4'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
以及:
/usr/bin/codesign --force --sign 128F9389E0B05671B3334551D3E46A04FDD716B2 --resource-rules=安装包制作目录build/Release-iphoneos/DCloud_Pandora.app/ResourceRules.plist --entitlements 安装包制作目录build/Pandora.build/Release-iphoneos/Pandora.build/DCloud_Pandora.app.xcent 安装包制作目录build/Release-iphoneos/DCloud_Pandora.app
Warning: --resource-rules has been deprecated in Mac OS X >= 10.10!
128F9389E0B05671B3334551D3E46A04FDD716B2: no identity found
Command /usr/bin/codesign failed with exit code 1
解决方法:
请参考http://ask.dcloud.net.cn/article/152教程导出正确的私钥(.p12)文件
5. 提示doesn't support the Push Notifications capability错误
BuildConfigure Failed 31015 编译错误
xcode build 开始
// ...
=== BUILD TARGET Pandora OF PROJECT Pandora WITH THE DEFAULT CONFIGURATION (Release) ===
Check dependencies
Provisioning profile "XXXXXXXX" doesn't support the Push Notifications capability.
Provisioning profile "XXXXXXXX" doesn't include the aps-environment entitlement.
Code signing is required for product type 'Application' in SDK 'iOS 10.0'
** BUILD FAILED **
The following build commands failed:
Check dependencies
(1 failure)
解决方法:
请参考http://ask.dcloud.net.cn/article/1088
如用户遇到打包问题按照以上方法无法排除请联系管理员
收起阅读 »启动界面、封面图片、Splash关不掉,一直转圈,无法进入
应用启动时为了提升用户体验(不显示黑屏)需设置启动界面,相关配置参考Manifest.json文件中的“应用图标和启动图片”章节。
启动界面的默认逻辑是应用启动时显示,此时在后台异步加载应用的入口页面(通常为index.html),当入口页面加载完成后(webview的loaded事件触发)自动关闭启动界面并显示入口页面。
注意:uni-app项目的启动界面设置请参考 https://uniapp.dcloud.net.cn/collocation/manifest
自定义启动界面关闭逻辑
但有时默认的启动界面关闭逻辑不能满足需求,需要自定义启动界面关闭逻辑。
比如index.html页面渲染非常慢,虽然dom构建完成了,但屏幕渲染未完成,此时关闭启动界面,就会看到不完整的index.html甚至白屏,此时需要延时或代码控制启动界面关闭;
再比如有时index.html的onload里面做了大量消耗资源的操作,比如预载了很多webview,如果直接关闭掉启动界面,index.html也是无法被用户流畅操作的,此时不如启动界面多显示一会,等待预载等js操作结束后再关闭启动界面。
在应用manifest.json文件的plus->splashscreen节点下通过属性来控制启动界面的关闭策略:![]() |
属性名称 | 作用 |
|---|---|---|
| autoclose | Boolean类型,控制是否自动关闭程序启动界面,true表示自动关闭,false表示需调用plus.navigator.closeSplashscreen()进行关闭,通常在打开入口页面时还需要做一些额外的业务逻辑等待操作(如提交服务器更新数据,预创建Webview窗口等)时使用。默认值为true。 | |
| delay | Number类型,控制启动界面延迟关闭时间,仅在autoclose属性设置为"true"时有效,用于定义程序启动界面在应用的首界面加载完毕后延迟关闭的时间,单位为ms,默认值为0。 | |
| waiting | Boolean类型,控制启动界面是否显示系统等待框,true表示显示系统等待框,false表示不显示系统等待框,默认值为false。 |
常见启动界面问题
应用一直停留在启动界面无法进入应用
查看manifest.json中plus->splashscreen节点下的autoclose属性值,如果设置为false:
则需要查看应用的入口页面(index.html)中是否正确调用plus.navigator.closeSplashscreen()方法?
- 通常如果不需要做一些业务逻辑等待(如等待服务器返回数据、预创建Webview窗口等)操作的情况,应该直接将autoclose属性值设置true*
HBuilder新建的空白App默认是自动关闭启动画面的,但官方的几个示例,如Hello H5+、Hello mui的启动图片都是在首页的plusready里手动关闭的。如果开发者新建了示例模板应用,又删除了首页plusready里的plus.navigator.closeSplashscreen(),就会导致应用停留在启动界面无法进入。 - 切记不要用页面初始时使用alert()
如果你在plus ready里调用了plus.navigator.closeSplashscreen(),但是在该代码生效前使用了alert,那么由于alert阻断了后续代码的执行,根本无法执行到closeSplashscreen,进而导致启动封面关不掉。
是否可自定义html页面作为应用启动界面
App云端打包不支持,如果有原生开发环境,则可以使用5+ SDK做原生开发来实现。
应用启动时为了提升用户体验(不显示黑屏)需设置启动界面,相关配置参考Manifest.json文件中的“应用图标和启动图片”章节。
启动界面的默认逻辑是应用启动时显示,此时在后台异步加载应用的入口页面(通常为index.html),当入口页面加载完成后(webview的loaded事件触发)自动关闭启动界面并显示入口页面。
注意:uni-app项目的启动界面设置请参考 https://uniapp.dcloud.net.cn/collocation/manifest
自定义启动界面关闭逻辑
但有时默认的启动界面关闭逻辑不能满足需求,需要自定义启动界面关闭逻辑。
比如index.html页面渲染非常慢,虽然dom构建完成了,但屏幕渲染未完成,此时关闭启动界面,就会看到不完整的index.html甚至白屏,此时需要延时或代码控制启动界面关闭;
再比如有时index.html的onload里面做了大量消耗资源的操作,比如预载了很多webview,如果直接关闭掉启动界面,index.html也是无法被用户流畅操作的,此时不如启动界面多显示一会,等待预载等js操作结束后再关闭启动界面。
在应用manifest.json文件的plus->splashscreen节点下通过属性来控制启动界面的关闭策略:![]() |
属性名称 | 作用 |
|---|---|---|
| autoclose | Boolean类型,控制是否自动关闭程序启动界面,true表示自动关闭,false表示需调用plus.navigator.closeSplashscreen()进行关闭,通常在打开入口页面时还需要做一些额外的业务逻辑等待操作(如提交服务器更新数据,预创建Webview窗口等)时使用。默认值为true。 | |
| delay | Number类型,控制启动界面延迟关闭时间,仅在autoclose属性设置为"true"时有效,用于定义程序启动界面在应用的首界面加载完毕后延迟关闭的时间,单位为ms,默认值为0。 | |
| waiting | Boolean类型,控制启动界面是否显示系统等待框,true表示显示系统等待框,false表示不显示系统等待框,默认值为false。 |
常见启动界面问题
应用一直停留在启动界面无法进入应用
查看manifest.json中plus->splashscreen节点下的autoclose属性值,如果设置为false:
则需要查看应用的入口页面(index.html)中是否正确调用plus.navigator.closeSplashscreen()方法?
- 通常如果不需要做一些业务逻辑等待(如等待服务器返回数据、预创建Webview窗口等)操作的情况,应该直接将autoclose属性值设置true*
HBuilder新建的空白App默认是自动关闭启动画面的,但官方的几个示例,如Hello H5+、Hello mui的启动图片都是在首页的plusready里手动关闭的。如果开发者新建了示例模板应用,又删除了首页plusready里的plus.navigator.closeSplashscreen(),就会导致应用停留在启动界面无法进入。 - 切记不要用页面初始时使用alert()
如果你在plus ready里调用了plus.navigator.closeSplashscreen(),但是在该代码生效前使用了alert,那么由于alert阻断了后续代码的执行,根本无法执行到closeSplashscreen,进而导致启动封面关不掉。
是否可自定义html页面作为应用启动界面
App云端打包不支持,如果有原生开发环境,则可以使用5+ SDK做原生开发来实现。










