更新记录
1.0.12(2024-02-23)
- 修复个别机型iOS公共响应头不生效问题
1.0.11(2024-02-18)
- 修复Android公共响应头问题
1.0.10(2024-02-07)
- 增加设置公共响应头接口
平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:4.4 - 14.0 | armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 | 适用版本区间:11 - 17 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
前言
wrs-httpserver是Android、iOS搭建APP本地web service的插件,常用的场景有:
- app本地离线播放m3u8视频
- app本地浏览web网站,支持绝对路径,_www ,_doc,_documents,_downloads等相对路径需要转成本地绝对路径,下面有转换方法。
更多强大功能(get/post请求、文件上传下载等)请使用插件https://ext.dcloud.net.cn/plugin?id=13647
UTS版本https://ext.dcloud.net.cn/plugin?id=15876
功能
- 启动http service,可配置多个web站点服务 注意:如果需要使用plus.io的API,需要配置项目的manifest.json里,把app-plus下的runmode改为liberate,具体原理参考uniapp官网
wrs-httpserver插件
场景 1. 直接访问在uniapp项目源码里的web站点
String.prototype.endWith = function(endStr) {
var d = this.length - endStr.length;
return (d >= 0 && this.lastIndexOf(endStr) == d)
}
var httpServer = uni.requireNativePlugin("wrs-httpserver");
// 把_www相对路径转为绝对路径
var absPath = plus.io.convertLocalFileSystemURL('_www');
// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾
if (absPath.endWith('/')) {
absPath = absPath.substring(0, absPath.length - 1);
}
var params = {
port: 8030, // http service的端口
staticWebs: [
{
urlPath: '/register', // 站点请求的url
directoryPath: absPath + '/static/registerSys' // web站点文件绝对路径,这个路径是绝对路径
},
{
urlPath: '/login',
directoryPath: absPath + '/static/loginSys'
}
],
uploadFilePath: uploadFilePath // 文件上传下载路径,目前仅对iOS生效,服务启动后,通过 http://ip:端口 访问文件目录
};
httpServer.startServer(params, (resp) => {
if (resp.code == 0) {
console.log("httpServer启动成功:" + resp.serverHost);
} else {
console.log("httpServer启动失败:" + resp.msg);
}
});
启动成功后,在浏览器输入resp.serverHost + port + urlPath + 网站文件,如:
http://192.168.6.31:8030/register/index.html
http://192.168.6.31:8030/login/index.html
loginSys、loginSys这两个站点的源码放到HBuildx项目里的static文件夹里
- -- 项目名
- --- static
- ---- loginSys
- ---- registerSys
uploadFilePath:文件上传下载管理路径,目前只支持iOS,文件管理的站点代码在demo目录iOSFileUploadWebSite文件夹
具体看右图
场景 2. 通过接口网络下载web站点源码并访问
// 下载web站点压缩文件
uni.downloadFile({
url: "http://192.168.6.89:8080/video/registerSys.zip", //仅为示例,并非真实的资源
success: (res) => {
if (res.statusCode === 200) {
var zipfile = res.tempFilePath;
// 下载后的压缩文件解压到_downloads目录
var targetPath = '_downloads/';
var absPath = plus.io.convertLocalFileSystemURL(targetPath);
// 经测试,修正在华为Android 10的系统上解压的解压目录,Android上使用绝对路径
switch (uni.getSystemInfoSync().platform) {
case 'android':
targetPath = plus.io.convertLocalFileSystemURL(targetPath);
break;
case 'ios':
targetPath = '_downloads/';
break;
default:
break;
}
plus.zip.decompress(zipfile, targetPath,
function() {
var path = plus.io.convertLocalFileSystemURL(targetPath);
console.log('解压成功绝对路径:' + path);
},
function(error) {
console.log('解压解压失败:' + error);
});
} else {
console.log('下载失败');
}
}
});
解压后_downloads目录已经有站点文件了,在启动http server时把_downloads下的站点也加进入即可:
// _www ,_doc,_documents,_downloads
var staticWebs = [];
var paths = ['_www', '_downloads'];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var absPath = plus.io.convertLocalFileSystemURL(path);
// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾
if (absPath.endWith('/')) {
absPath = absPath.substring(0, absPath.length - 1);
}
switch (i) {
case 0: {
staticWebs.push({
urlPath: '/staticLoginSys',
directoryPath: absPath + '/static/loginSys',
});
staticWebs.push({
urlPath: '/',
directoryPath: absPath + '/static/registerSys',
});
}
break;
case 1: {
staticWebs.push({
urlPath: '/downloadsSys',
directoryPath: absPath + '/registerSys',
});
}
break;
default:
break;
}
console.log('path:' + path + ' 绝对路径:' + absPath);
}
var appid = plus.runtime.appid;
var params = {
port: 8030,
staticWebs: staticWebs
};
this.staticWebs = staticWebs;
httpServer.startServer(params, (resp) => {
if (resp.code == 0) {
console.log("httpServer启动成功:" + resp.serverHost);
} else {
console.log("httpServer启动失败:" + resp.msg);
}
});
_downloads下web站点的访问地址是:
http://192.168.6.31:8030/downloadsSys/index.html
停止http server服务
httpServer.stopServer()
判断http server服务是否在运行
var obj = httpServer.isRuning();
if(obj.isRuning) {
console.log("httpServer服务正在运行");
} else {
console.log("httpServer服务没有运行");
}
增加公共响应头(一般用于解决跨域问题)
var header = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS, DELETE, PUT",
"Access-Control-Allow-Headers": "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,lang,access-token"
}
httpServer.setCommonResponseHeader(header)
如果Android打包时出现如下错误,请再次提交打包,这是uniapp云打包下载库没有及时下载到造成的,需要多试几次
Appid: xxx
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:checkReleaseAarMetadata'.
> Could not resolve all files for configuration ':app:releaseRuntimeClasspath'.
> Could not resolve xxx.
Required by:
project :app
> Could not resolve xxxxxxxxx.
> Could not get resource 'https://dl.google.com/dl/android/maven2/com/xxxxxx-xxxx.pom'.
完整代码
<template>
<div>
<text>HttpServer</text>
<button @click="startServer">启动服务</button>
<button @click="stopServer">暂停服务</button>
<button @click="serverIsRunning">服务是否在运行</button>
<button @click="downloads">下载站点</button>
<text class="log">{{msg}}</text>
</div>
</template>
<script>
String.prototype.endWith = function(endStr) {
var d = this.length - endStr.length;
return (d >= 0 && this.lastIndexOf(endStr) == d)
}
var httpServer = uni.requireNativePlugin("wrs-httpserver");
export default {
data() {
return {
msg: "",
url: "http://192.168.6.89:8080/video/registerSys.zip"
}
},
methods: {
startServer: function() {
// _www ,_doc,_documents,_downloads
var staticWebs = [];
var paths = ['_www', '_downloads'];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var absPath = plus.io.convertLocalFileSystemURL(path);
// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾
if (absPath.endWith('/')) {
absPath = absPath.substring(0, absPath.length - 1);
}
switch (i) {
// _www
case 0: {
staticWebs.push({
urlPath: '/staticLoginSys', // 站点请求的url
directoryPath: absPath + '/static/loginSys',// web站点文件绝对路径,这个路径是绝对路径
});
staticWebs.push({
urlPath: '/staticRegisterSys',
directoryPath: absPath + '/static/registerSys',
});
}
break;
// _downloads
case 1: {
staticWebs.push({
urlPath: '/downloadsSys',
directoryPath: absPath + '/registerSys',
});
}
break;
case 2: {
staticWebs.push({
urlPath: '/documentsSys',
directoryPath: absPath + '/registerSys',
});
}
break;
case 3: {
staticWebs.push({
urlPath: '/docSys',
directoryPath: absPath + '/registerSys',
});
}
break;
default:
break;
}
console.log('path:' + path + ' 绝对路径:' + absPath);
}
var appid = plus.runtime.appid;
var params = {
port: 8030, // 端口
staticWebs: staticWebs
};
// 启动http service
httpServer.startServer(params, (resp) => {
if (resp.code == 0) {
console.log("httpServer启动成功:" + resp.serverHost);
} else {
console.log("httpServer启动失败:" + resp.msg);
}
});
},
stopServer: function() {
// 停止http server
httpServer.stopServer();
},
serverIsRunning: function(){
var obj = httpServer.isRuning();
if(obj.isRuning) {
console.log("httpServer服务正在运行");
} else {
console.log("httpServer服务没有运行");
}
},
downloads: function() {
uni.downloadFile({
url: this.url, //仅为示例,并非真实的资源
success: (res) => {
if (res.statusCode === 200) {
var zipfile = res.tempFilePath;
var targetPath = '_downloads/';
var absPath = plus.io.convertLocalFileSystemURL(targetPath);
// 经测试,修正在华为Android 10的系统上解压的解压目录,Android上使用绝对路径
switch (uni.getSystemInfoSync().platform) {
case 'android':
targetPath = plus.io.convertLocalFileSystemURL(targetPath);
break;
case 'ios':
targetPath = '_downloads/';
break;
default:
break;
}
plus.zip.decompress(zipfile, targetPath,
function() {
var path = plus.io.convertLocalFileSystemURL(targetPath);
console.log('解压成功绝对路径:' + path);
},
function(error) {
console.log('解压解压失败:' + error);
});
} else {
console.log('下载失败');
}
}
});
},
showMsg: function(msg) {
// httpServer.log({
// msg: msg
// });
this.msg = msg;
},
logPath: function() {
var paths = ['_www', '_downloads', '_doc', '_documents'];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var absPath = plus.io.convertLocalFileSystemURL(path);
console.log('path:' + path + ' 绝对路径:' + absPath);
}
}
}
}
</script>
组件文档:https://www.jianshu.com/p/543d28b22716