手把手教你如使用七牛云对象存储,小程序和h5前端封装(附demo代码)

七牛云对象存储(Kodo)是一款稳定、安全、高效、易用的云存储服务,适用于各种场景下的数据存储需求。本文将详细介绍如何在项目中集成七牛云对象存储,并分别提供小程序端和H5端的实现代码。

准备工作

1. 注册七牛云账号

首先访问七牛云官网注册账号并完成实名认证。

2. 创建存储空间(Bucket)

登录七牛云控制台后:

  1. 进入"对象存储"服务

  2. 点击"创建存储空间"

  3. 填写Bucket名称(需全局唯一)

  4. 选择存储区域(根据用户分布选择)

  5. 设置访问控制(建议先设置为公开,后续可按需调整)

3. 获取必要凭证

在"个人中心" > "密钥管理"中获取:

  • Access Key (AK)

  • Secret Key (SK) 

 核心讲解

一、核心上传流程

七牛云文件上传的核心流程分为三步:

  1. 获取上传凭证(uptoken)

  2. 初始化上传器并配置参数

  3. 执行上传并处理结果

二、前端核心代码

1. 初始化上传器

通用配置参数:

const config = {
  bucket: 'your-bucket',      // 存储空间名称
  region: 'z0',              // 存储区域(z0-华东,z1-华北等)
  uptoken: '',               // 上传凭证(通常从服务端获取)
  domain: 'https://xxx.com', // 空间绑定的域名
  shouldUseQiniuFileName: false // 是否使用七牛生成的文件名
};

2、获取服务端给的token和key(key可以是前端写死,但是最好还是用后端传的,交给后端来控制) 

// 获取七牛云上传token
async function getQiniuUploadToken() {
  try {
    const res = await api.getQiniuAccesstoekn()
    if (res.code !== 200) {
      throw new Error(res.message || '获取七牛云token失败')
    }
    return res.data
  }
  catch (error) {
    console.error('获取七牛云token失败:', error)
    throw error
  }
}

3、发起请求,上传文件

初始化上传任务

const observable = qiniu.upload(
      file,           // 文件对象/路径
      key,            // 文件保存的名称
      config.uptoken, // 上传凭证
      { region: config.region }, // 额外配置
      { useCdnDomain: true }     // 使用CDN加速
    );

订阅上传进度

const subscription = observable.subscribe({
      next: (res) => {
        console.log('上传进度:', res.total.percent);
      },
      error: (err) => {
        console.error('上传失败:', err);
        reject(err);
      },
      complete: (res) => {
        // 拼接完整URL
        const fileUrl = `${config.domain}/${res.key}`;
        console.log('上传完成:', fileUrl);
        resolve({
          ...res,
          fileUrl: fileUrl
        });
      }
    });

封装demo(h5和小程序)

H5demo

import api from '@/api/module/cos'
import * as qiniu from 'qiniu-js'

// 七牛云配置
const qiniuConfig = {
  uploadDomain: 'https://upload.qiniup.com' // 华东,
  cdnDomain: 'cdn域名',
  maxRetryCount: 2,
  timeout: 3000,
}

// 获取七牛云上传token
async function getQiniuUploadToken() {
  try {
    const res = await api.getQiniuAccesstoekn()
    if (res.code !== 200) {
      throw new Error(res.message || '获取七牛云token失败')
    }
    return res.data
  }
  catch (error) {
    console.error('获取七牛云token失败:', error)
    throw error
  }
}

/**
 * 高级七牛云文件上传(H5版)
 * @param {object} options 上传选项
 * @param {File} options.file 文件对象
 * @param {string} options.cloudPath 云端存储路径
 * @param {Function} [options.onProgress] 上传进度回调
 * @param {Function} [options.onCancel] 取消上传回调
 * @param {number} [options.retryCount] 当前重试次数
 * @returns {Promise<{url: string, key: string, hash: string}>} 上传结果
 */
async function uploadFileToQiniuH5(options) {
  const {
    file,
    cloudPath,
    onProgress = () => { },
    onCancel = () => { },
    retryCount = 0,
  } = options

  try {
    // 获取上传token
    const { token, key } = await getQiniuUploadToken()
    const cloudFile = `${key}/${cloudPath}`

    // 配置上传选项
    const putExtra = {
      fname: file.name,
      params: {},
      mimeType: file.type || null,
    }

    const config = {
      useCdnDomain: true,
      region: qiniu.region.z0, // 华东区域
      retryCount: qiniuConfig.maxRetryCount,
      disableStatisticsReport: false,
    }

    // 执行上传
    return new Promise((resolve, reject) => {
      let subscription = null
      let timer = null

      // 超时处理
      timer = setTimeout(() => {
        if (subscription) {
          subscription.unsubscribe()
        }
        reject(new Error('上传超时'))
      }, qiniuConfig.timeout)

      const observable = qiniu.upload(
        file,
        cloudFile,
        token,
        putExtra,
        config,
      )

      subscription = observable.subscribe({
        next: (response) => {
          // 进度更新
          onProgress({
            loaded: response.total.loaded,
            total: response.total.size,
            percent: Math.round(response.total.percent),
          })
        },
        error: (err) => {
          clearTimeout(timer)
          // 重试逻辑
          if (retryCount < qiniuConfig.maxRetryCount) {
            console.log(`准备第${retryCount + 1}次重试...`)
            setTimeout(() => {
              uploadFileToQiniuH5({
                ...options,
                retryCount: retryCount + 1,
              }).then(resolve).catch(reject)
            }, 1000 * (retryCount + 1))
          }
          else {
            reject(new Error(`上传失败: ${err.message}`))
          }
        },
        complete: (res) => {
          clearTimeout(timer)
          console.log('上传成功:', res)
          resolve({
            url: `${qiniuConfig.cdnDomain}/${res.key}`,
            key: res.key,
            hash: res.hash,
          })
        },
      })

      // 提供取消上传的方法
      onCancel(() => {
        clearTimeout(timer)
        if (subscription) {
          subscription.unsubscribe()
        }
        reject(new Error('上传已取消'))
      })
    })
  }
  catch (error) {
    console.error('上传文件到七牛云失败:', error)
    throw error
  }
}

/**
 * 简化版上传(H5版)
 * @param {File} file 文件对象
 * @param {string} cloudPath 云端存储路径
 * @returns {Promise<string>} 文件URL
 */
async function simpleUploadH5(file, cloudPath) {
  const result = await uploadFileToQiniuH5({
    file,
    cloudPath,
    onProgress: (progress) => {
      console.log(`上传进度: ${progress.percent}%`)
    },
  })
  return result.url
}


export {
  simpleUploadH5,
  uploadFileToQiniuH5,
}

小程序demo

import { getQiniuAccesstoekn } from '../api/module/cos'

// 七牛云配置
const qiniuConfig = {
  uploadDomain: 'https://upload.qiniup.com' //华东,
  // 你的CDN域名
  cdnDomain: 'cdn域名',
  // 上传重试次数
  maxRetryCount: 2,
  timeout: 3000
};

// 获取七牛云上传token
const getQiniuUploadToken = async () => {
  try {
    const res = await getQiniuAccesstoekn();
    if (res.code !== 200) {
      throw new Error(res.message || '获取七牛云token失败');
    }
    return res.data;
  } catch (error) {
    console.error('获取七牛云token失败:', error);
    throw error;
  }
};

/**
 * 高级七牛云文件上传
 * @param {Object} options 上传选项
 * @param {string} options.filePath 本地文件路径
 * @param {string} options.cloudPath 云端存储路径
 * @param {Function} [options.onProgress] 上传进度回调
 * @param {Function} [options.onCancel] 取消上传回调
 * @param {number} [options.retryCount=0] 当前重试次数
 * @returns {Promise<{url: string, key: string, hash: string}>} 上传结果
 */
const uploadFileToQiniu = async (options) => {
  const {
    filePath,
    cloudPath,
    onProgress = () => { },
    onCancel = () => { },
    retryCount = 0
  } = options;

  try {
    // 获取上传token
    const { token, key } = await getQiniuUploadToken();

    const cloudFile = `${key}/${cloudPath}`

    // 获取文件信息
    const fileInfo = await new Promise((resolve, reject) => {
      wx.getFileInfo({
        filePath,
        success: resolve,
        fail: reject
      });
    });

    // 执行上传
    return new Promise((resolve, reject) => {
      let uploadTask = null;
      let timer = null;

      // 超时处理
      timer = setTimeout(() => {
        if (uploadTask) {
          uploadTask.abort();
        }
        reject(new Error('上传超时'));
      }, qiniuConfig.timeout);

      uploadTask = wx.uploadFile({
        url: qiniuConfig.uploadDomain,
        filePath,
        name: 'file',
        formData: {
          token,
          key: cloudFile
        },
        success: (res) => {
          clearTimeout(timer);
          if (res.statusCode === 200) {
            try {
              const data = JSON.parse(res.data);
              console.log('上传成功:', data);

              resolve({
                url: `${qiniuConfig.cdnDomain}/${data.key}`,
                key: data.key,
                hash: data.hash
              });
            } catch (e) {
              reject(new Error('解析响应数据失败'));
            }
          } else {
            reject(new Error(`上传失败: ${res.data}`));
          }
        },
        fail: (err) => {
          clearTimeout(timer);
          // 重试逻辑
          if (retryCount < qiniuConfig.maxRetryCount) {
            console.log(`准备第${retryCount + 1}次重试...`);
            setTimeout(() => {
              uploadFileToQiniu({
                ...options,
                retryCount: retryCount + 1
              }).then(resolve).catch(reject);
            }, 1000 * (retryCount + 1));
          } else {
            reject(new Error(`上传失败: ${err.errMsg}`));
          }
        },
        complete: () => {
          clearTimeout(timer);
        }
      });

      // 确保uploadTask存在再绑定事件
      if (uploadTask && uploadTask.onProgressUpdate) {
        uploadTask.onProgressUpdate((res) => {
          onProgress({
            loaded: res.totalBytesSent,
            total: res.totalBytesExpectedToSend,
            percent: res.progress
          });
        });
      }

      // 提供取消上传的方法
      onCancel(() => {
        clearTimeout(timer);
        if (uploadTask) {
          uploadTask.abort();
        }
        reject(new Error('上传已取消'));
      });
    });
  } catch (error) {
    console.error('上传文件到七牛云失败:', error);
    throw error;
  }
};

/**
 * 简化版上传
 * @param {string} filePath 本地文件路径
 * @param {string} cloudPath 云端存储路径
 * @returns {Promise<string>} 文件URL
 */
const simpleUpload = async (filePath, cloudPath) => {
  const result = await uploadFileToQiniu({
    filePath,
    cloudPath,
    onProgress: (progress) => {
      console.log(`上传进度: ${progress.percent}%`);
    }
  });

  return result.url;
};

export {
  uploadFileToQiniu,
  simpleUpload
};

注意:在小程序端可以直接请求七牛云的域名,h5用七牛云的时候用qiniu.upload的时候报错,控制台说这个方法没有被定义,但是我是按照官方的文档写的,我用的版本是最新的4.X meta版本,但是换到3.1.2版本就不会有报错了,可能是API更新了官方的文档没有更新之类的,或者其他原因导致的

内容概要:本文围绕“单相逆变器闭环逆变电路PWM模型仿真研究”展开,基于Simulink平台构建单相逆变器的闭环控制系统仿真模型,重点研究PWM调制技术在逆变电路中的应用与实现。文中详细阐述了系统架构设计、电压电流双闭环控制策略的实现原理、控制器参数设计及仿真建模全过程,并通过仿真结果验证了控制方案在动态响应、稳态精度与系统稳定性方面的有效性。同时,文档还涵盖多种电力电子系统典型应用场景,如多类型短路故障仿真(中性点不接地、经小电阻接地、经消弧线圈接地等)、软开关技术、微电网能量管理、MPPT控制等,体现出较强的技术综合性和工程实践价值。; 适合人群:电气工程、自动化、电力电子与新能源等相关专业的高校本科生、研究生、科研人员,以及从事电力系统仿真、逆变器设计与新能源并网技术研发的工程技术人员。; 使用场景及目标:①掌握基于Simulink的单相逆变器闭环控制系统建模与PWM仿真方法;②深入理解双闭环控制、SPWM/SVPWM调制、系统稳定性分析等核心技术原理;③为课程设计、毕业设计、科研项目或实际工程开发提供可复用的仿真模型与技术支持; 阅读建议:建议结合文中仿真模型动手实践,重点掌握PI控制器参数整定、PWM信号生成机制与仿真结果分析方法,同时可延伸学习文档中涉及的软开关、故障仿真、微电网控制等关联技术,以拓展系统级设计能力。
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
内容概要:本文系统阐述了CUDA并行计算的核心优化技巧,围绕提升SM利用率、最大化内存带宽、隐藏访存延迟和减少指令开销四大目标,从GPU硬件架构、线程模型、内存访问、指令执行、内核设计及工程实践六个维度展开。重点讲解了线程块配置、Warp分支发散规避、全局内存合并访问、共享内存Bank冲突避免、寄存器与常量内存使用、异步传输与多流并行、快速数学函数、原子操作优化、内核拆分与融合、Tensor Core利用等关键技术,并提供了编译优化参数和Nsight系列性能分析工具的使用指导,形成了一套完整的CUDA性能优化方法论。; 适合人群:具备CUDA编程基础,从事高性能计算、深度学习、科学计算或GPU加速开发的工程师与研究人员,尤其适合工作2年以上的开发者提升底层优化能力。; 使用场景及目标:①解决CUDA程序中SM利用率低、内存带宽不足、访存延迟高等性能瓶颈;②掌握从基础到高阶的系统性优化策略,实现程序性能的指数级提升;③结合Nsight工具进行性能剖析与迭代优化。; 阅读建议:学习时应结合实际代码调试与性能分析工具(如Nsight Compute和Nsight Systems)进行验证,优先实施线程块配置、合并访问、-O3编译等低成本高回报的基础优化,再逐步深入共享内存优化、内核融合、Tensor Core利用等高阶技术,同时推荐优先使用cuBLAS、cuDNN等NVIDIA官方优化库以逼近硬件极限性能。
内容概要:本文提供了一份完整的“大学生创新创业训练计划项目”申报材料模板包,围绕“基于深度学习的智能垃圾分类回收箱设计与实现”项目,详细展示了从项目申报书、答辩PPT、中期检查表到结题报告的全套规范文档。内容涵盖项目背景、目标、研究内容、技术路线、创新点、进度安排、预期成果、经费预算及风险应对等关键环节,并以实际案例呈现各阶段成果,如YOLOv8轻量级模型识别准确率达96%、单台成本控制在780元、校园试点回收520kg可回收物、获得软著与论文成果等,形成可复制推广的校园绿色解决方案。; 适合人群:参与大学生创新创业训练计划(大创项目)的本科生团队,尤其是工科类、计算机相关专业、有意向开展人工智能+环保类实践项目的1-3年级学生;同时也适用于指导教师和项目评审人员作为参考模板。; 使用场景及目标:①帮助学生团队系统规划并撰写高质量的大创项目申报书与结题报告;②指导项目全过程管理,包括技术实施、进度控制、经费使用与成果凝练;③支撑项目答辩展示,提升项目规范性与竞争力,冲击“互联网+”“挑战杯”等赛事奖项; 阅读建议:此资源不仅提供文本模板,更体现了项目从立项到结题的完整逻辑链条,使用者应结合自身课题,参照其结构化表达方式、量化目标设定和技术落地路径进行模仿与创新,注重理论与实践结合,强化数据支撑与成果可视化。
内容概要:本文提供了一个基于Simulink的光伏储能单相逆变器并网仿真模型,系统实现了并网逆变电路的PWM调制控制、闭环控制策略及并网运行特性的仿真分析,涵盖系统建模、控制算法设计、稳定性验证与动态性能评估等关键环节。该模型不仅支持对单相逆变器在并网过程中的电流谐波、功率因数、电能质量及系统稳定性的深入研究,还可拓展应用于多类型电力系统仿真场景,如MPPT控制、软开关技术、微电网能量管理、短路故障分析(包括单相、两相接地及相间短路)、直流电机双闭环控制、Buck/Boost类变换器控制等,展现出广泛的科研适配性与工程实践价值。; 适合人群:面向具备电力电子、自动控制理论或电气工程背景,熟练掌握Simulink/Matlab仿真工具,从事新能源发电系统、微电网控制、逆变器拓扑与控制策略研究的硕士/博士研究生、科研人员及电力系统相关领域的工程技术人员。; 使用场景及目标:①开展光伏发电系统并网控制策略的设计与仿真验证;②学习并掌握单相逆变器PWM调制、锁相环(PLL)、电压电流双闭环控制等核心技术的建模方法;③作为课程设计、毕业设计或科研项目的仿真平台,支撑控制系统开发与优化;④结合文中提供的多种电力系统案例(如故障仿真、储能控制、微网调度),进行横向对比与综合能力提升; 阅读建议:建议读者结合文中列出的多个仿真案例进行扩展学习,重点关注控制器参数设计与系统动态响应之间的关系,动手复现模型并进行仿真调试,通过改变负载、电网条件或控制参数,深入理解并网逆变器的工作机理与控制规律,从而提升实际科研与工程应用能力。
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
因为工作需要,每天需要打很多次卡,然后忙起来就忘了,忙完了就会想,刚才打卡了吗?弄错就会漏打卡了,漏打卡会有处罚。就想到写一个程序来解决这个痛点。就有了本次发布的这个程序。 PHP项目,修改起来也简单,也方便二开。本来就是H5页面布局,部署好,直接手机浏览器打开,或者使用封装工具,封装成apk。本人已打包为微信小程序,使用起来很方便。 项目简介 本项目是一个多用户打卡记录系统,基于 PHP + MySQL 开发,提供简洁的用户打卡功能和记录管理。 核心功能 功能模块 描述 用户认证 支持用户注册、登录、密码修改、密码重置 打卡功能 用户可进行每日打卡,记录打卡时间 记录查询 支持按日期查询打卡记录 用户管理 支持头像上传、个人信息查看 数据统计 提供打卡统计功能 技术特点 轻量级架构:纯 PHP 开发,无需框架依赖,部署简单 响应式设计:移动端友好的 UI 界面,支持触摸操作 安全性: 使用 prepare + bind_param 防止 SQL 注入 密码采用哈希加密存储 Session 会话管理用户状态 模块化设计:API 接口与前端分离,便于扩展 项目结构 Plain Text ├── api/ # RESTful API 接口 │ ├── checkin.php # 打卡接口 │ ├── login.php # 登录接口 │ ├── register.php # 注册接口 │ ├── records.php # 记录查询接口 │ ├── stats.php # 统计接口 │ └── … ├── config/ # 配置文件 │ ├── database.php # 数据库配置 │ └── auth.php # 认证配置 ├── sql/ # 数据库脚本 │ └── init.sql # 初始化脚本 ├── avatars/ # 头像存储目录 ├── ind
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值