更新记录

1.0.3(2023-12-14)

  1. Android增加自定义ContentType

1.0.2(2023-08-16)

  1. 更新Android文件下载问题

1.0.1(2023-08-14)

  1. 修复Android下载大文件一直卡住问题
查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:4.4 - 14.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 适用版本区间:9 - 17

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
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原生插件配置”->”云端插件“列表中删除该插件重新选择


前言

HttpServe是Android、iOS搭建APP本地web service的插件

功能

  1. app本地浏览多个静态web网站,支持自定义路径、_www 、_doc、_documents、_downloads等路径
  2. 支持get、post等请求,自定义返回数据,数据类型支持json、html
  3. 支持文件上传下载
  4. 搭建本地服务播放本地hls/m3u8视频
  5. 支持跨域
  6. 支持后台运行,后台运行配置请使用插件https://ext.dcloud.net.cn/plugin?id=10450

注意:如果需要使用plus.io的API,需要配置项目的manifest.json里,把app-plus下的runmode改为liberate,具体原理参考uniapp官网

UTS版本https://ext.dcloud.net.cn/plugin?id=15876

支持定制QQ252797991

wrs-httpServe插件


var httpServe = uni.requireNativePlugin("wrs-httpServe");

场景 1 app本地浏览多个静态web网站


            httpServe.addWebsite({
                url: "/loginSys/.*?", // 站点请求的url,采用正则可以匹配站点下所有资源的请求
                fileDir: absPath + '/static/loginSys' // web站点文件绝对路径,这个路径是绝对路径
            }, () => {
                // 添加addWebsite完成
            });

启动成功后,在浏览器输入host + port + urlPath + 网站文件,如:


http://192.168.6.31:8888/loginSys/index.html

场景 2 支持get、post等请求,自定义返回数据,数据类型支持json、html

  • Get请求

            httpServe.get({
                url: "/get"
            }, (request) => {
                this.showMsg("Get request:" + JSON.stringify(request))
                // 返回JSON数据
                this.sendJSONResponse(request)
                // ios:
                // {"urlParams":{"name":"wrs"},"url":"http://172.16.11.44:8888/get?name=wrs","method":"GET","headers":{"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36","Upgrade-Insecure-Requests":"1","Accept-Encoding":"gzip, deflate","Connection":"keep-alive","Host":"172.16.11.44:8888","Accept-Language":"zh-CN,zh;q=0.9","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"},"path":"/get"}
            }, (resp) => {
                // 添加get完成
            });

访问地址:


http://192.168.6.31:8888/get
  • Post请求,支持x-www-form-urlencoded、raw-JSON

            httpServe.post({
                url: "/post"
            }, (request) => {
                this.showMsg("Post request:" + JSON.stringify(request))
                this.sendJSONResponse(request)
            }, () => {
                // 添加post完成
            });

访问地址:


http://192.168.6.31:8888/post
  • Post请求,支持form-data

            httpServe.postFormData({
                url: "/postFormData"
            }, (request) => {
                this.showMsg("Post request:" + JSON.stringify(request))
                this.sendJSONResponse(request)
            }, () => {
                // 添加post完成
            });

访问地址:


http://192.168.6.31:8888/postFormData
  • get/post返回响应数据
  1. 返回json数据

                let path = request.path
                let response = {
                    type: "json", // 数据类型,支持json、html、text、file
                    value: {  // 对应数据类型的值
                        "name": "张三",
                        "info": {
                            "age": 12
                        },
                        teams: [{
                            "name": "xxx"
                        }]
                    },
                    headers: { // 响应头
                        token: "xxxx-xx"
                    }
                }
                var params = {};
                params.path = path; // request请求path
                params.response = response;
                httpServe.sendResponse(params)
  1. 返回html数据

                let path = request.path
                let response = {
                    type: "html",
                    value: '<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>你好,我是html</body></html>',
                    headers: {
                        token: "xxxx-xx"
                    }
                }
                var params = {};
                params.path = path;
                params.response = response;
                httpServe.sendResponse(params)
  1. 返回文件,相当于下载文件

                var absPath = plus.io.convertLocalFileSystemURL("_www")
                // Android获取的absPath以/结尾,iOS获取的absPath不是/结尾 
                if (absPath.endWith('/')) {
                    absPath = absPath.substring(0, absPath.length - 1)
                }
                var filePath = absPath + '/static/video/movie.mp4'
                let path = request.path
                let response = {
                    type: "file",
                    value: filePath, // 本地文件绝对路径
                    headers: {
                        token: "xxxx-xx"
                    }
                }
                var params = {};
                params.path = path;
                params.response = response;
                httpServe.sendResponse(params)
  1. 返回text数据

                let path = request.path
                let response = {
                    type: "text",
                    value: '你好,我是text',
                    headers: {
                        token: "xxxx-xx"
                    }
                }
                var params = {};
                params.path = path;
                params.response = response;
                httpServe.sendResponse(params)

场景 3 支持文件上传下载

  • 文件上传

            var targetPath = '_downloads';
            var saveDir = plus.io.convertLocalFileSystemURL(targetPath);
            if (saveDir.endWith('/')) {
                saveDir = saveDir.substring(0, saveDir.length - 1)
            }
            if (this.isAndroid) {
                // Android上传文件保存到sdcard目录比较方便查看
                saveDir = "/sdcard"
            }

            httpServe.uploadFile({
                url: "/uploadFile",
                saveDir: saveDir // 文件保存路径,android 11以上的系统如果没有文件访问权限,需要通过requestManagerPermission接口来请求权限,否则文件保存会失败
            }, (request) => {
                this.showMsg("uploadFile request:" + JSON.stringify(request))

                this.sendJSONResponse(request)
                // ios:
                // {"remoteAddress":"172.16.11.60:59430","body":{"age":{"isFile":false,"value":"20"},"name":{"isFile":false,"value":"wrs"},"file":{"fileName":"text.txt","isFile":true,"path":"/var/mobile/Containers/Data/Application/0365A8A9-B926-4571-9C4D-C251DC7AAB26/Library/Caches/Pandora/downloads/text.txt"}},"urlParams":{},"url":"http://172.16.11.44:8888/uploadFile","localAddress":"172.16.11.44:8888","method":"POST","headers":{"User-Agent":"PostmanRuntime/7.32.3","Accept":"*/*","Content-Length":"651","Content-Type":"multipart/form-data; boundary=--------------------------445338919225193221741331","Host":"172.16.11.44:8888","Postman-Token":"d1501ccd-0e2e-407d-89ad-6604f3e3b76f","Accept-Encoding":"gzip, deflate, br","Connection":"keep-alive"},"path":"/uploadFile"}
            }, () => {
                // 添加uploadFile完成
            });
  • 下载某个特定文件

            // 下载某个特定文件
            httpServe.downloadFile({
                url: "/downloadFile",
                filePath: absPath + '/static/logo.png'
            }, (request) => {

            }, () => {
                // 添加downloadFile完成
            });
  • 下载某个文件夹下的文件

            //  // 下载某个目录下的文件
            httpServe.addWebsite({
                url: "/downloadDirFile/.*?",
                fileDir: absPath + '/static/loginSys'
            }, () => {
                // 添加addWebsite完成
            });

场景 3 搭建本地服务播放本地hls/m3u8视频


            //  // 播放地址:http://172.16.11.44:8888/video/hls/index.m3u8
            httpServe.addWebsite({
                url: "/video/hls/.*?",
                fileDir: absPath + '/static/video/hls'
            }, () => {
                // 添加addWebsite完成
            });

启动http server服务


                var params = {};
                params.port = parseInt(this.port)
                httpServe.start(params, (resp) => {
                    if (this.isAndroid) { // android
                        httpServe.getMobileIPAddress((resp) => {
                            this.accessHost = "http://" + resp.host + ":" + this.port
                            this.printAccessUrl()
                        })

                    } else { // ios
                        this.showMsg(JSON.stringify(resp))
                        let flag = resp.flag
                        if (flag) {
                            this.accessHost = resp.host;
                            this.printAccessUrl()
                        } else {
                            this.showMsg("启动http server失败" + resp.error)
                        }
                    }
                })

启动http server服务


                httpServe.stop(() => {
                    this.showMsg("Http Server已停止")
                })

判断http server服务是否在运行


 httpServe.isRunning((resp)=>{
     if(resp.isRuning) {
         console.log("httpServe服务正在运行");
     } else {
         console.log("httpServe服务没有运行");
     }

 });
  • 获取IP地址,仅支持Android,iOS的IP通过启动服务的数据返回

                        httpServe.getMobileIPAddress((resp) => {
                            this.accessHost = "http://" + resp.host + ":" + this.port
                            this.printAccessUrl()
                        })
  • 判断是否有访问存储目录权限,仅支持Android

                        httpServe.isExternalStorageManager((resp) => {
                            var flag = resp.flag
                        })
  • 请求访问存储目录权限,仅支持Android

                httpServe.requestManagerPermission({
                    requestCode: 1200
                });
  • 设置自定义的ContentType,仅支持Android

                httpServe.setCustomContentType({
                    ".css": "text/css;charset=utf-8",
                    ".js": "application/javascript"
                });

如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android: <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> ios: 无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问