上传文件(Node.js)

最近更新时间:2023-01-11 10:41:06

查看PDF
  • 简单上传

以下代码用于上传小于5G的文件到指定到的存储空间,上传的同时可设置ACL、storageClass。

client.object.put({
  Bucket: '<bucketName>',
  FilePath: '',// 待上传文件路径,必填
  Key: '<objectKey>', // 唯一的key,必填
  StorageClass: '', // 存储类型STANDARD/STANDARD_IA/ARCHIVE,非必填
  ACL: '',// 访问控制private/public-read,非必填
  headers: {}// 自定义header信息,非必填
}, function (rerr, data, response, body) {
  console.log(response.statusCode)// 成功返回200
})
  • 分块上传

以下代码适用于上传超过5G的文件到指定存储空间。

分块上传分三步:
1. 初始化
2. 上传分块
3. 合并分块

// 1.初始化
client.object.multitpart_upload_init({
  Bucket: '<bucketName>',
  Key: '<objectKey>', // 必填
  ACL: '', // 访问控制,非必填
  StorageClass: '', // 存储类型,非必填
  headers: {} // 非必填
}, function (rerr, data, response, body) {
  console.log(data) // data中会包含后续上传需要的UploadId
})

// 2.上传分块
// notice: 上传分块前需要自行对文件进行分块处理
client.object.upload_part({
  Bucket: '<bucketName>',
  Key: '<objectKey>', // 必填
  PartNumber: '', // 必填, 上传的块id
  UploadId: '', // 必填, 上传的uploadid
  Body: '' // 必填, 分块数据
}, function (rerr, data, response, body) {
    console.log(response.statusCode) // 上传成功返回200
    console.log(response.headers.etag) // 上传成功返回etag,后面合并分块会用到
})

// 3.合并分块
client.object.upload_complete({
  Bucket: '<bucketName>',
  Key: '<objectKey>', // 必填
  UploadId: '', // 必填, 上传的uploadid
  Body: '' // 必填, 所有分块数据的集合,以xml格式传递
}, function (rerr, data, response, body) {
  console.log(data)
})

完整的示例:

function upload() {
    const bucket = '' // 上传的桶
    const key = '' // 上传的key
    const filePath = '' // 文件路径
    const chunkSize = 5*1024*1024 // 分块大小
    const contentType = '' // 文件类型
    let uploadId = '' // 上传id
    const fileSize = 100*1025*1024 // 文件大小
    const count = parseInt(fileSize / chunkSize) + ((fileSize % chunkSize == 0 ? 0: 1));     // 总块数
  
    const initParams = {
        Key: key,
        Bucket: bucket
    }
    client.object.multitpart_upload_init(initParams, function (err, data, res, body) {

        data = util.xml2json.parser(data) // util为sdk内部的工具类
      
        uploadId = data.InitiateMultipartUploadResult.UploadId
        console.log(`获取到上传id: ${uploadId}`)
      
        client.config({
            dataType: 'xml'
        });

        let chunkNum = 0;

        let etags = [] // 存放上传成功的分块etag

        console.log('开始分块上传...')

        up();

        function up() {
            let start = chunkNum * chunkSize
            console.log(`开始上传 第${chunkNum} 块文件...`)
            // 是否全部上传
            if (chunkNum < count) {
                util.getChunk(filePath, chunkSize, start, function (buffer) {
                    const params = {
                        Bucket: bucket,
                        Key: key,
                        UploadId: uploadId,
                        PartNumber: chunkNum + 1, // 传值从1开始
                        Body: buffer,
                        Type: contentType
                    }
                    console.log('分块上传参数:', params)
                    client.object.upload_part(params, function (err, data, res, body) {
                        if (err) {
                            throw err;
                        } else {
                            const etag = res.headers.etag;
                            console.log(`上传成功,获取etag信息:${etag}`)
                            etags.push(etag)
                            chunkNum++;
                            up();
                        }
                    })
                })
            } else {
                // 合并上传的分块
                const params = {
                    Bucket: bucket,
                    Key: key,
                    PartNumber: count,
                    Type: contentType,
                    UploadId: uploadId,
                    Body: util.generateCompleteXML(arr) // 将分块数据转成xml
                }
                console.log('合并参数:', params)
                client.object.upload_complete(params, function (err, data, res, body) {
                    if (err) throw err;
                    console.log('上传成功,合并文件:', err, data)
                })
            }
        }
    });
}

说明: 该完整示例没有对异常做处理,是种理想情况下的场景。建议是结合自身的业务调整逻辑。其他具体说明需要查看文档

  • 流式上传
client.object.put({
  Bucket: '<bucketName>',
  Key: '<objectKey>', // 唯一的key,必填
  Body: ''// stream,必填
}, function (rerr, data, response, body) {
  console.log(response.statusCode)// 成功返回200
})
  • 上传回调

回调原理:

回调.png

client.object.put({
  Bucket: '<bucketName>',
  Key: '<objectKey>', // 唯一的key,必填
  FilePath: '',// 待上传文件路径,必填
  headers: {
    'x-kss-callbackurl':"<应用服务器地址>", //回调地址
    'x-kss-callbackbody': 'etag=${etag}&objectSize=${objectSize}&key=${key}',
    'x-kss-callbackauth': '1',// 是否开启验证
    'kss-location': 'test'
  }
}, function (rerr, data, response, body) {
  console.log(response.statusCode)// 成功返回200
})

说明:

  • headers内的回调参数未做校验,请确保传参正确
  • callbackbody:支持自定义参数、常量、魔法变量。对于魔法变量可以简单理解为约定好的固定变量,使用时直接用${变量名}格式即可取到相应的值。常用的魔法变量参考文档说明
  • 如果callbackurl不可达,则会报错。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Error>
  <Code>CallbackFail</Code>
  <Message>call back server is fail</Message>
  <Resource>/bucketName/a.mp4?callback=''</Resource>
</Error>

文档内容是否对您有帮助?

根本没帮助
文档较差
文档一般
文档不错
文档很好

在文档使用中是否遇到以下问题

内容不全,不深入
内容更新不及时
描述不清晰,比较混乱
系统或功能太复杂,缺乏足够的引导
内容冗长

更多建议

0/200

评价建议不能为空

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

问题反馈