uni-app客户端时间和服务器不一致导致uniCloud.uploadFile上传失败?

发布于 1周前 作者 htzhanglong 来自 Uni-App

uni-app客户端时间和服务器不一致导致uniCloud.uploadFile上传失败?

示例代码:

/**
 * 上传文件
 * @param {String} filePath 微信选择文件的临时文件名  
 */
function uploadImg(filePath) {  
  // 后缀,如.png  
  const suffix = filePath.substr(filePath.lastIndexOf('.')).toLowerCase()  
  const fileName = `user/${new Date().getTime()}${suffix}`  

  return new Promise((resolve, reject) => {  
    uniCloud.uploadFile({  
      filePath,  
      cloudPath: fileName,  
      onUploadProgress: progressEvent => {  
        const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)  
        console.log(percentCompleted)  
      },  
      success: res => {  
        console.debug('@upload success', res)  

        resolve(res.fileID)  
      },  
      fail: e => {  
        console.error('error upload = ', e)  

        reject(e)  
      },  
      complete: () => {  

      }  
    })  
  })  
}

操作步骤:

  1. 将自己的设备时间调慢几分钟
  2. 在客户端调用uniCloud.uploadFile()方法

预期结果:

正常上传或返回可以理解的错误信息

实际结果:

提示 Error: request has expired 其他没有什么有价值的错误信息

bug描述:

客户端时间和服务器时间导致uniCloud.uploadFile上传失败

不确定是和服务器时间不一致还是和北京时间不一致

可以解释下为什么会这样和怎么解决吗?


4 回复

这不是bug, 是支付宝在请求的时候会带上时间戳进行签名, 如果时间戳和支付宝服务器的时间戳相差太大, 就会拒绝访问, 因此手机上的时间必须调整跟北京时间的时间戳对齐


好的,就是说国外用户就用不了了,而且客户端还要校验下时间,不然有些用户会提示莫名的错误

回复 Junan_: 国外用户可以用的,世界各地的时间时区不一样,但是时间戳是一样的

在uni-app中,如果客户端时间和服务器时间不一致,可能会导致一些与时间相关的操作(如签名验证、时间戳校验等)失败,从而影响到uniCloud.uploadFile的上传过程。为了解决这个问题,你可以采取以下几种策略,确保时间的一致性或进行相应的时间校正。以下是一些代码示例和思路:

1. 获取服务器时间并同步

在上传文件之前,你可以先从服务器获取当前时间,并同步到客户端。这可以通过一个API请求来实现。

// 假设你有一个API可以返回服务器时间
uni.request({
    url: 'https://yourserver.com/api/gettime',
    success: (res) => {
        const serverTime = new Date(res.data.serverTime);
        // 你可以将serverTime保存到全局变量或localStorage中,以便后续使用
        syncLocalTime(serverTime);
        
        // 继续执行上传操作
        uploadFile();
    },
    fail: (err) => {
        console.error('Failed to get server time:', err);
    }
});

function syncLocalTime(serverTime) {
    // 这里只是一个示例,实际中不建议直接修改系统时间
    // 你可以选择在应用内部维护一个时间偏移量
    const timeDiff = serverTime - new Date();
    // 保存timeDiff以便后续使用
}

function uploadFile() {
    // 使用uniCloud.uploadFile上传文件
    uniCloud.uploadFile({
        cloudPath: 'your-cloud-path',
        filePath: 'your-local-file-path',
        success: () => {
            console.log('File uploaded successfully');
        },
        fail: (err) => {
            console.error('File upload failed:', err);
        }
    });
}

2. 在服务器端处理时间校验

如果可能的话,你可以在服务器端放宽时间校验的规则,或者在生成签名时考虑时间偏移量。这样,即使客户端时间有轻微的偏差,也不会影响上传操作。

3. 使用时间戳生成签名

如果你使用签名来验证上传请求,确保签名生成时使用的是服务器时间。你可以将服务器时间作为签名的一部分,或者在生成签名前从服务器获取时间。

4. 定期检查并更新客户端时间

你可以在应用启动时、或每隔一段时间自动从服务器获取并同步时间,确保客户端时间尽量接近服务器时间。

通过上述方法,你可以有效减少因时间不一致导致的uniCloud.uploadFile上传失败问题。在实际应用中,选择最适合你业务需求的方案进行实施。

回到顶部