Uniapp/微信小程序授权设置并实现点击保存图片

一:需要用到的API

1.uni.authorize(OBJECT)     -- 提前向用户发起授权请求。

uni.authorize({
  scope: 'scope.userInfo',
  success() {
    console.log('授权成功');
  }
});

:如果用户之前拒绝了授权,此接口会直接进入失败回调。一般需要搭配uni.getSettinguni.openSetting使用。

2.uni.getSetting (Object object)   --获取用户的当前设置消息

uni.getSetting({
  success(res) {
    if (res.authSetting['scope.userInfo']) {
      console.log('用户已授权');
    } else {
      console.log('用户未授权');
    }
  }
});

3.uni.openSetting(Object object)  --用户手动进行授权设置

uni.openSetting();

4.uni.uploadFile(OBJECT)   --将本地资源上传到开发者服务器

5.uni.downloadFile(OBJECT)  --下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径。

6. uni.saveImageToPhotosAlbum(OBJECT)   --保存图片到系统相册

二:思路

1.过程

1.判断用户是否授权保存图片到系统相册

    1:如果未授权(两种情况):调授权再保存图片

       (1)用户第一次调用 (uni.authorize) 

       (2)用户之前拒绝授权 (uni.openSetting)

                        如果之前拒绝,过阵子想再次保存,需要判断是否第一次授权

  (注意:前面已经提过了authorize只弹窗一次,如果之前拒绝过了,接口直接进入失败回调,所以需要判断是否首次)

    2:如果已授权:直接保存图片

三:代码实现

 1.先配置:manifest.json

"mp-weixin": {
		"permission": {
			"scope.writePhotosAlbum": {
				"desc": "你的图片将保存到手机相册"
			  }
		},
	},

注: 微信小程序在2023年10月17日之后,使用API需要配置​​​​​​隐私协议

------获取具体信息请移步官方文档uni.chooseImage(OBJECT) | uni-app官网

2. 保存图片功能代码实现:(无判断授权情况)

  downSaveImage(imgurl) {
    uni.showModal({
      title: '保存图片',
      content: '是否保存当前图片?',
      success: (res) => {
        if (res.confirm) {
          uni.downloadFile({
            url: imgurl,//图片地址
            success: (res) => {
              if (res.statusCode === 200) {
                // console.log(res.tempFilePath,'res.tempFilePathres.tempFilePath');
                uni.saveImageToPhotosAlbum({
                  filePath: res.tempFilePath,
                  success: function () {
                    uni.showToast({
                      title: '保存成功',
                      duration: 2000,
                    })
                  },
                  fail: function () {
                    uni.showToast({
                      title: '保存失败,请稍后重试',
                      icon: 'none',
                    })
                  },
                })
              }
            },
          })
        } else if (res.cancel) {
          uni.showToast({
          	title: "你取消了该操作",
          	icon:'none',
          	duration: 2000
          });
        }
      },
    })
  },

(2)用户授权情况部分代码

  downSaveImage(imgurl) {
    uni.getSetting({
      success(res) {
        if (res.authSetting['scope.writePhotosAlbum']) {
          // 已授权,直接保存图片
          //这里写保存图片代码.......
        } else if (res.authSetting['scope.writePhotosAlbum'] === false) {
          // 用户已拒绝授权,提示用户授权
          uni.showModal({
            title: '提示',
            content: '您未授权保存图片到相册,是否前往设置页面进行授权?',
            success: function (res) {
              if (res.confirm) {
                uni.openSetting({
                  success: function (res) {
                    if (res.authSetting['scope.writePhotosAlbum']) {
                      //这里写保存图片代码.......
                    }
                  },
                })
              } else if (res.cancel) {
                uni.showToast({
                  title: '您取消了授权',
                  icon: 'none',
                  duration: 2000,
                })
              }
            },
          })
        } else {
          // 用户第一次调用,调用授权接口
          uni.authorize({
            scope: 'scope.writePhotosAlbum',
            success() {
              //这里写保存图片代码.......
            },
            fail() {
              uni.showToast({
                title: '授权失败,请稍后重试',
                icon: 'none',
                duration: 2000,
              })
            },
          })
        }
      },
    })
  },

(3)添加授权+保存图片功能的完整代码

downSaveImage(imgurl) {
  uni.getSetting({
    success(res) {
      if (res.authSetting['scope.writePhotosAlbum']) {
        // 已授权,直接保存图片
        uni.downloadFile({
          url: imgurl,
          success: (res) => {
            if (res.statusCode === 200) {
              uni.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: function () {
                  uni.showToast({
                    title: '保存成功',
                    duration: 2000,
                  })
                },
                fail: function () {
                  uni.showToast({
                    title: '保存失败,请稍后重试',
                    icon: 'none',
                  })
                },
              })
            }
          },
        })
      } else if (res.authSetting['scope.writePhotosAlbum'] === false) {
        // 用户已拒绝授权,提示用户授权
        uni.showModal({
          title: '提示',
          content: '您未授权保存图片到相册,是否前往设置页面进行授权?',
          success: function (res) {
            if (res.confirm) {
              uni.openSetting({
                success: function (res) {
                  if (res.authSetting['scope.writePhotosAlbum']) {
                    uni.downloadFile({
                      url: imgurl,
                      success: (res) => {
                        if (res.statusCode === 200) {
                          uni.saveImageToPhotosAlbum({
                            filePath: res.tempFilePath,
                            success: function () {
                              uni.showToast({
                                title: '保存成功',
                                duration: 2000,
                              })
                            },
                            fail: function () {
                              uni.showToast({
                                title: '保存失败,请稍后重试',
                                icon: 'none',
                              })
                            },
                          })
                        }
                      },
                    })
                  }
                },
              })
            } else if (res.cancel) {
              uni.showToast({
                title: '您取消了授权',
                icon: 'none',
                duration: 2000,
              })
            }
          },
        })
      } else {
        // 用户第一次调用,调用授权接口
        uni.authorize({
          scope: 'scope.writePhotosAlbum',
          success() {
            uni.downloadFile({
              url: imgurl,
              success: (res) => {
                if (res.statusCode === 200) {
                  uni.saveImageToPhotosAlbum({
                    filePath: res.tempFilePath,
                    success: function () {
                      uni.showToast({
                        title: '保存成功',
                        duration: 2000,
                      })
                    },
                    fail: function () {
                      uni.showToast({
                        title: '保存失败,请稍后重试',
                        icon: 'none',
                      })
                    },
                  })
                }
              },
            })
          },
          fail() {
            uni.showToast({
              title: '授权失败,请稍后重试',
              icon: 'none',
              duration: 2000,
            })
          },
        })
      }
    },
  })
}

四:项目中注意的问题:

1.微信小程序模拟器可以保存图片,但是手机真机调试不行。

问题描述:项目中如果图片地址是后台返回的临时地址,在微信小程序模拟器返回的地址开头是:

http://tmp/.......jpg

但是真机上调试返回图片地址开头是:

wxfile://tmp/......jpg

原因:临时地址是没用的,需要使用uni.uploadFile上传到服务器上转换永久地址

代码:

   uni.uploadFile({
        url: 'https://app.wugongyuan.cn/api/common/uploadFile', // 上传的服务器地址
        filePath: res, // 临时文件路径
        name: 'file', // 上传文件的字段名
        success: function (res) {
          this.upLoadImgUrl = JSON.parse(res.data).data.fileUrl
          console.log(this.upLoadImgUrl, 'upImgUrl---------------')
          // 为什么一直先走下面的
          // setTimeout(()=>{
          console.log(this.upLoadImgUrl, 'this.upLoadImgUrl')

          // that.downSaveImage(this.upLoadImgUrl)
          that.$tools.downSaveImage(this.upLoadImgUrl)
          // },5000)
        },
        fail: function (error) {
          console.log(error)
          // 处理上传失败的情况
        },
      })

以上会引起作用域this指向问题 ,可以参考另一篇文章函数内引入外部函数的调用顺序问题及解决方案-CSDN博客

2.小程序开发者工具和真机调试上传图片都可以,体验版,开发,正式都不行

在小程序后台=>开发管理=>服务器域名下面设置下uploadFile合法域名就可以了

原因:在小程序开发过程中,特别是在微信小程序、QQ小程序或其他类似平台的小程序开发环境中,当你需要实现上传文件(例如上传图片、文档或其他类型文件到服务器)的功能时,这个服务器的域名必须事先在“服务器域名”列表中进行白名单配置。如果没有正确配置,小程序在试图上传文件至未经允许的域名时,会因为安全策略而遭到拦截,导致上传失败

3.必须要先授权请求(authSetting

如果直接(openSetting)让用户手动设置授权,打开的只是之前已经授权过的权限,看不到未请求的内容

要用户先拒绝授权再引导用户手动打开设置页面进行授权。这样用户在设置页面中就能看到所有的权限内容,包括未请求的权限,从而能够正确地进行授权操作。

ps:之前一直打开手动的,没有授权过,所以就没有想要的授权按钮,耗了好久还以为是什么大bug..........

### 如何使用 UniApp 开发微信小程序实现视频上传与预览功能 #### 前端页面设计 为了实现UniApp 中开发微信小程序的视频上传和预览功能,前端页面的设计至关重要。可以创建两个主要界面:一个是用于选择本地视频文件执行上传操作;另一个则是展示已上传视频供用户观看。 对于视频的选择与上传部分,在 `pages/index.vue` 文件内定义如下组件: ```vue <template> <view class="container"> <!-- 显示当前选中的视频缩略图 --> <video id="myVideo" :src="tempFilePath"></video> <!-- 视频选择按钮 --> <button type="primary" @click="chooseVideo">选择视频</button> <!-- 提交上传按钮 --> <button v-if="!uploading && tempFilePath !== ''" type="warn" @click="doUpload">上传视频</button> <!-- 正在上传提示 --> <text v-if="uploading">{{ progress }}%</text> </view> </template> <script> export default { data() { return { tempFilePath: '', // 存储临时路径 uploading: false, progress: 0 // 记录上传进度百分比 } }, methods: { chooseVideo() { uni.chooseVideo({ success(res) { this.tempFilePath = res.tempFilePath; }.bind(this), fail(err) { console.error('选择失败', err); } }); }, doUpload() { const that = this; wx.uploadFile({ url: 'http://your.server/api/upload', filePath: this.tempFilePath, name: 'file', formData: {}, header: {'content-type': 'multipart/form-data'}, success(uploadRes) { if (JSON.parse(uploadRes.data).success === true){ uni.showToast({title:'上传成功'}); }else{ uni.showModal({ content: JSON.stringify(JSON.parse(uploadRes.data)), showCancel:false}); } }, onProgressUpdate(progressEvent) { that.progress = Math.floor((progressEvent.totalBytesSent / progressEvent.totalBytesExpectedToSend)*100); } }); this.uploading = true; } } } </script> ``` 此代码片段实现了基本的视频选取以及通过 `wx.uploadFile()` 方法向指定 URL 发送 POST 请求完成上传过程[^1]。 #### 后端接口调用及服务器配置 后端服务需要提供接收来自客户端发送过来的数据流的能力,将其存储至适当位置(如云储存)。这里假设采用 Node.js 和 Express 框架作为后台技术栈来处理 HTTP 请求。 安装必要的依赖包: ```bash npm install express multer cors body-parser ``` 编写简单的路由逻辑以支持文件上传: ```javascript const path = require('path'); const fs = require('fs'); const express = require('express'); const multer = require('multer'); // 创建Express应用实例 let app = express(); // 配置Multer中间件解析表单数据 var storage = multer.diskStorage({ destination(req, file, cb) {cb(null,'./uploads/')}, filename(req,file,callback){callback(null,new Date().toISOString()+path.extname(file.originalname))} }); let upload = multer({storage}).single('file'); app.use(express.json()); app.use(cors()); // 处理POST请求 - 图片上传API endpoint app.post('/api/upload',(req,res,next)=>{ try { upload(req, res,function(error){ if (!error){ let response={ message:"File uploaded successfully", fileName:req.file.filename }; res.status(200).send(response); } else { throw new Error(`Error during file upload ${error.message}`); } }) } catch(e){ next(new Error(e)); } }) // 错误处理器 app.use(function(err, req, res, next) { console.log(err.stack); res.status(500).json({ error: "Something went wrong!" }); }); // 设置静态资源目录以便可以直接访问上传后的文件 app.use("/uploads", express.static(path.join(__dirname,"uploads"))); // 监听端口启动HTTP server app.listen(process.env.PORT || 3000,()=>{ console.log("Server started"); }) ``` 这段脚本设置了一个 RESTful API `/api/upload` 来接受从前端传来的多媒体文件将它们保存到磁盘上的特定文件夹中。同时启用了 CORS 支持跨源资源共享。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值