fix(privacy): 修复微信隐私协议导致的chooseImage错误
- 在 app.config.ts 的requiredPrivateInfos中添加chooseImage和chooseMedia权限声明 - 在上传文件接口uploadFile中调用ensurePrivacyAuthorized函数,预先检查用户隐私授权 - 在 app.tsx 的 useLaunch 钩子中注册 onNeedPrivacyAuthorization 回调,自定义弹窗提示用户协议 - ensurePrivacyAuthorized兼容旧版本微信基础库,未提供隐私授权函数时默认放行 - 更新文档说明隐私协议错误码errno:112的原因及修复方案 - 提醒绕过uploadFile调用chooseImage的页面需单独添加隐私授权预检机制
This commit is contained in:
@@ -53,11 +53,52 @@ const computeSignature = (accessKeySecret: string, canonicalString: string): str
|
||||
return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在调用涉及用户隐私的 API(chooseImage / chooseMedia / getLocation 等)前,
|
||||
* 等待用户完成微信隐私协议授权。基础库 3.16.1+ 强制要求,未授权会抛 errno:112。
|
||||
* 旧基础库或不支持隐私协议的版本直接放行。
|
||||
*/
|
||||
const ensurePrivacyAuthorized = (): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
const wxAny: any = Taro
|
||||
if (typeof wxAny.requirePrivacyAuthorize !== 'function') {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (typeof wxAny.getPrivacySetting === 'function') {
|
||||
wxAny.getPrivacySetting({
|
||||
success: (res: any) => {
|
||||
if (res && res.needAuthorization) {
|
||||
wxAny.requirePrivacyAuthorize({
|
||||
success: () => resolve(),
|
||||
fail: () => resolve(),
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
},
|
||||
fail: () => resolve(),
|
||||
})
|
||||
} else {
|
||||
wxAny.requirePrivacyAuthorize({
|
||||
success: () => resolve(),
|
||||
fail: () => resolve(),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传阿里云OSS
|
||||
*/
|
||||
export async function uploadFile() {
|
||||
return new Promise(async (resolve: (result: FileRecord) => void, reject) => {
|
||||
// 修复:基础库 3.16.1+ 强制隐私协议校验,先确保用户已同意
|
||||
try {
|
||||
await ensurePrivacyAuthorized()
|
||||
} catch {
|
||||
// 忽略前置授权错误,让 chooseImage 自己抛具体的 fail
|
||||
}
|
||||
Taro.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
|
||||
@@ -140,7 +140,7 @@ export default {
|
||||
desc: '用于获取您的位置,按距离展示附近门店和选择收货地址定位',
|
||||
},
|
||||
},
|
||||
requiredPrivateInfos: ['getLocation', 'chooseLocation'],
|
||||
requiredPrivateInfos: ['getLocation', 'chooseLocation', 'chooseImage', 'chooseMedia'],
|
||||
tabBar: {
|
||||
custom: false,
|
||||
color: '#8a8a8a',
|
||||
|
||||
23
src/app.tsx
23
src/app.tsx
@@ -22,6 +22,29 @@ function App(props: AppProps) {
|
||||
if (savedTheme === 'light' || savedTheme === 'dark') {
|
||||
setTheme(savedTheme)
|
||||
}
|
||||
|
||||
// 微信隐私协议(基础库 3.16.1+ 强制)
|
||||
// 当小程序使用 chooseImage/chooseMedia/getLocation 等接口时,若用户未在隐私协议中同意,
|
||||
// 微信会回调这里,开发者必须弹一个自定义的协议确认弹窗,并提供"同意并继续"/"拒绝"两个分支。
|
||||
const wxAny: any = Taro
|
||||
if (typeof wxAny.onNeedPrivacyAuthorization === 'function') {
|
||||
wxAny.onNeedPrivacyAuthorization((resolve: any) => {
|
||||
wxAny.showModal({
|
||||
title: '用户隐私协议',
|
||||
content: '为了正常使用图片上传、拍照、定位等功能,需要您同意《用户隐私协议》。',
|
||||
confirmText: '同意',
|
||||
cancelText: '拒绝',
|
||||
success: (modalRes: any) => {
|
||||
if (modalRes.confirm) {
|
||||
resolve({ event: 'agree', button: 'agree' })
|
||||
} else {
|
||||
resolve({ event: 'disagree' })
|
||||
}
|
||||
},
|
||||
fail: () => resolve({ event: 'disagree' }),
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
useDidShow(() => {})
|
||||
|
||||
Reference in New Issue
Block a user