From daf4387e2d69ab428e2ecac465e3e657eaba34ae Mon Sep 17 00:00:00 2001 From: chrisftian Date: Sat, 13 Nov 2021 17:06:36 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0appendObject?= =?UTF-8?q?=EF=BC=9B=E5=A2=9E=E5=8A=A0=E4=B8=89=E4=B8=AA=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo-album/lib/cos-wx-sdk-v5.js | 187 +++++++++++++++++++++++++++++++- demo/demo-sdk.js | 64 +++++++++++ demo/lib/cos-wx-sdk-v5.js | 187 +++++++++++++++++++++++++++++++- lib/request.js | 41 ++++++- package.json | 2 +- src/base.js | 36 +++++- src/ci.js | 99 +++++++++++++++++ src/cos.js | 4 +- src/util.js | 2 +- 9 files changed, 606 insertions(+), 16 deletions(-) create mode 100644 src/ci.js diff --git a/demo-album/lib/cos-wx-sdk-v5.js b/demo-album/lib/cos-wx-sdk-v5.js index f6be7ef..7490658 100644 --- a/demo-album/lib/cos-wx-sdk-v5.js +++ b/demo-album/lib/cos-wx-sdk-v5.js @@ -254,7 +254,7 @@ var getFileMd5 = function (body, callback) { function clone(obj) { return map(obj, function (v) { - return typeof v === 'object' ? clone(v) : v; + return typeof v === 'object' && v !== null ? clone(v) : v; }); } @@ -2287,6 +2287,7 @@ var event = __webpack_require__(4); var task = __webpack_require__(16); var base = __webpack_require__(17); var advance = __webpack_require__(23); +var ci = __webpack_require__(25); var defaultOptions = { SecretId: '', @@ -2337,9 +2338,10 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); +ci.init(COS); COS.getAuthorization = util.getAuth; -COS.version = '1.0.13'; +COS.version = '1.1.0'; module.exports = COS; @@ -8098,6 +8100,37 @@ function multipartAbort(params, callback) { }); } +/** + * 追加上传 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {File || Blob || String} params.Body 上传文件对象或字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 + */ + function appendObject(params, callback) { + submitRequest.call(this, { + Action: 'name/cos:AppendObject', + method: 'POST', + Bucket: params.Bucket, + Region: params.Region, + action: 'append', + Key: params.Key, + body: params.Body, + qs: { + position: params.Position + }, + headers: params.Headers, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + /** * cos 内置请求 @@ -8119,6 +8152,8 @@ function multipartAbort(params, callback) { headers: params.Headers, qs: params.Query, body: params.Body, + Url: params.Url, + rawBody: params.RawBody, }, function (err, data) { if (err) return callback(err); if (data && data.body) { @@ -8616,7 +8651,7 @@ function _submitRequest(params, callback) { var region = params.Region; var object = params.Key; var method = params.method || 'GET'; - var url = params.url; + var url = params.url || params.Url; var body = params.body; var json = params.json; var rawBody = params.rawBody; @@ -8811,6 +8846,7 @@ var API_MAP = { putObjectTagging: putObjectTagging, getObjectTagging: getObjectTagging, deleteObjectTagging: deleteObjectTagging, + appendObject: appendObject, // 分块上传相关方法 uploadPartCopy: uploadPartCopy, @@ -8852,10 +8888,47 @@ var obj2str = function (obj) { return list.join('&'); }; +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + case 'boolean': + return v ? 'true' : 'false'; + case 'number': + return isFinite(v) ? v : ''; + default: + return ''; + } +}; + +var queryStringify = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + if (typeof obj === 'object') { + return Object.keys(obj).map(function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (Array.isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).filter(Boolean).join(sep); + + } + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + var request = function (params, callback) { var filePath = params.filePath; var headers = params.headers || {}; - var url = params.url; + var url = params.url || params.Url; var method = params.method; var onProgress = params.onProgress; var requestTask; @@ -8926,7 +8999,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && obj2str(params.qs) || ''; + var qsStr = params.qs && queryStringify(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; } @@ -10352,6 +10425,110 @@ var async = { module.exports = async; +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +var util = __webpack_require__(0); + +/** + * 查询已经开通数据万象功能的存储桶 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ +function describeMediaBuckets(params, callback) { + var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Url: url + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件信息 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getMediaInfo(params, callback) { + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: { + 'ci-process': 'videoinfo' + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件某个时间的截图 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Number} params.Time 截图的时间点,单位为秒,必须 + * @param {Number} params.Width 截图的宽,非必须 + * @param {Number} params.Height 截图的高,非必须 + * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 + * @param {String} params.Rotate 图片旋转方式,非必须 + * @param {String} params.Mode 截帧方式,非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getSnapshot(params, callback) { + var query = { + 'ci-process': 'snapshot', + time: params.Time || 1, + width: params.Width || 0, + height: params.Height || 0, + format: params.Format || 'jpg', + rotate: params.Rotate || 'auto', + mode: params.Mode || 'exactframe', + }; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: query, + RawBody: true, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +var API_MAP = { + describeMediaBuckets: describeMediaBuckets, + getMediaInfo: getMediaInfo, + getSnapshot: getSnapshot, +}; + +module.exports.init = function (COS) { + util.each(API_MAP, function (fn, apiName) { + COS.prototype[apiName] = util.apiWrapper(apiName, fn); + }); +}; + /***/ }) /******/ ]); }); \ No newline at end of file diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index 134ec00..7f68e7c 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -352,6 +352,41 @@ var dao = { }); console.log(url); }, + appendObject: function() { + cos.appendObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + Body: '12345', + Position: 0, + }, + function(err, data) { + console.log(err || data); + }) + }, + appendObject_continue: function() { + cos.headObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + }, function(err, data) { + if (err) return console.log(err); + // 首先取到要追加的文件当前长度,即需要上送的Position + var position = data.headers['content-length']; + cos.appendObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + Body: '66666', + Position: position, + }, + function(err, data) { + // 也可以取到下一次上传的position继续追加上传 + // var nextPosition = data.headers['x-cos-next-append-position']; + console.log(err || data); + }) + }); + }, // Service getService: function() { cos.getService(requestCallback); @@ -624,6 +659,35 @@ var dao = { } }, requestCallback); }, + describeMediaBuckets: function() { + cos.describeMediaBuckets({ + Bucket: config.Bucket, + Region: config.Region, + }, + function(err, data){ + console.log(err || data); + }); + }, + getMediaInfo: function() { + cos.getMediaInfo({ + Bucket: config.Bucket, + Region: config.Region, + Key: '20.mp4', + }, + function(err, data){ + console.log(err || data); + }); + }, + getSnapshot: function() { + cos.getSnapshot({ + Bucket: config.Bucket, + Region: config.Region, + Key: '20.mp4', + }, + function(err, data){ + console.log(err || data); + }); + }, cancelTask: function() { cos.cancelTask(TaskId); console.log('canceled'); diff --git a/demo/lib/cos-wx-sdk-v5.js b/demo/lib/cos-wx-sdk-v5.js index f6be7ef..7490658 100644 --- a/demo/lib/cos-wx-sdk-v5.js +++ b/demo/lib/cos-wx-sdk-v5.js @@ -254,7 +254,7 @@ var getFileMd5 = function (body, callback) { function clone(obj) { return map(obj, function (v) { - return typeof v === 'object' ? clone(v) : v; + return typeof v === 'object' && v !== null ? clone(v) : v; }); } @@ -2287,6 +2287,7 @@ var event = __webpack_require__(4); var task = __webpack_require__(16); var base = __webpack_require__(17); var advance = __webpack_require__(23); +var ci = __webpack_require__(25); var defaultOptions = { SecretId: '', @@ -2337,9 +2338,10 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); +ci.init(COS); COS.getAuthorization = util.getAuth; -COS.version = '1.0.13'; +COS.version = '1.1.0'; module.exports = COS; @@ -8098,6 +8100,37 @@ function multipartAbort(params, callback) { }); } +/** + * 追加上传 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {File || Blob || String} params.Body 上传文件对象或字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 + */ + function appendObject(params, callback) { + submitRequest.call(this, { + Action: 'name/cos:AppendObject', + method: 'POST', + Bucket: params.Bucket, + Region: params.Region, + action: 'append', + Key: params.Key, + body: params.Body, + qs: { + position: params.Position + }, + headers: params.Headers, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + /** * cos 内置请求 @@ -8119,6 +8152,8 @@ function multipartAbort(params, callback) { headers: params.Headers, qs: params.Query, body: params.Body, + Url: params.Url, + rawBody: params.RawBody, }, function (err, data) { if (err) return callback(err); if (data && data.body) { @@ -8616,7 +8651,7 @@ function _submitRequest(params, callback) { var region = params.Region; var object = params.Key; var method = params.method || 'GET'; - var url = params.url; + var url = params.url || params.Url; var body = params.body; var json = params.json; var rawBody = params.rawBody; @@ -8811,6 +8846,7 @@ var API_MAP = { putObjectTagging: putObjectTagging, getObjectTagging: getObjectTagging, deleteObjectTagging: deleteObjectTagging, + appendObject: appendObject, // 分块上传相关方法 uploadPartCopy: uploadPartCopy, @@ -8852,10 +8888,47 @@ var obj2str = function (obj) { return list.join('&'); }; +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + case 'boolean': + return v ? 'true' : 'false'; + case 'number': + return isFinite(v) ? v : ''; + default: + return ''; + } +}; + +var queryStringify = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + if (typeof obj === 'object') { + return Object.keys(obj).map(function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (Array.isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).filter(Boolean).join(sep); + + } + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + var request = function (params, callback) { var filePath = params.filePath; var headers = params.headers || {}; - var url = params.url; + var url = params.url || params.Url; var method = params.method; var onProgress = params.onProgress; var requestTask; @@ -8926,7 +8999,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && obj2str(params.qs) || ''; + var qsStr = params.qs && queryStringify(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; } @@ -10352,6 +10425,110 @@ var async = { module.exports = async; +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +var util = __webpack_require__(0); + +/** + * 查询已经开通数据万象功能的存储桶 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ +function describeMediaBuckets(params, callback) { + var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Url: url + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件信息 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getMediaInfo(params, callback) { + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: { + 'ci-process': 'videoinfo' + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件某个时间的截图 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Number} params.Time 截图的时间点,单位为秒,必须 + * @param {Number} params.Width 截图的宽,非必须 + * @param {Number} params.Height 截图的高,非必须 + * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 + * @param {String} params.Rotate 图片旋转方式,非必须 + * @param {String} params.Mode 截帧方式,非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getSnapshot(params, callback) { + var query = { + 'ci-process': 'snapshot', + time: params.Time || 1, + width: params.Width || 0, + height: params.Height || 0, + format: params.Format || 'jpg', + rotate: params.Rotate || 'auto', + mode: params.Mode || 'exactframe', + }; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: query, + RawBody: true, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +var API_MAP = { + describeMediaBuckets: describeMediaBuckets, + getMediaInfo: getMediaInfo, + getSnapshot: getSnapshot, +}; + +module.exports.init = function (COS) { + util.each(API_MAP, function (fn, apiName) { + COS.prototype[apiName] = util.apiWrapper(apiName, fn); + }); +}; + /***/ }) /******/ ]); }); \ No newline at end of file diff --git a/lib/request.js b/lib/request.js index d5fdbb4..0668d32 100644 --- a/lib/request.js +++ b/lib/request.js @@ -10,10 +10,47 @@ var obj2str = function (obj) { return list.join('&'); }; +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + case 'boolean': + return v ? 'true' : 'false'; + case 'number': + return isFinite(v) ? v : ''; + default: + return ''; + } +}; + +var queryStringify = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + if (typeof obj === 'object') { + return Object.keys(obj).map(function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (Array.isArray(obj[k])) { + return obj[k].map(function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).filter(Boolean).join(sep); + + } + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + var request = function (params, callback) { var filePath = params.filePath; var headers = params.headers || {}; - var url = params.url; + var url = params.url || params.Url; var method = params.method; var onProgress = params.onProgress; var requestTask; @@ -84,7 +121,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && obj2str(params.qs) || ''; + var qsStr = params.qs && queryStringify(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; } diff --git a/package.json b/package.json index 593001e..006da04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cos-wx-sdk-v5", - "version": "1.0.13", + "version": "1.1.0", "description": "小程序 SDK for [腾讯云对象存储服务](https://cloud.tencent.com/product/cos)", "main": "demo/lib/cos-wx-sdk-v5.js", "scripts": { diff --git a/src/base.js b/src/base.js index ee2b6bf..71db3ce 100644 --- a/src/base.js +++ b/src/base.js @@ -2802,6 +2802,37 @@ function multipartAbort(params, callback) { }); } +/** + * 追加上传 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {File || Blob || String} params.Body 上传文件对象或字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 + */ + function appendObject(params, callback) { + submitRequest.call(this, { + Action: 'name/cos:AppendObject', + method: 'POST', + Bucket: params.Bucket, + Region: params.Region, + action: 'append', + Key: params.Key, + body: params.Body, + qs: { + position: params.Position + }, + headers: params.Headers, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + /** * cos 内置请求 @@ -2823,6 +2854,8 @@ function multipartAbort(params, callback) { headers: params.Headers, qs: params.Query, body: params.Body, + Url: params.Url, + rawBody: params.RawBody, }, function (err, data) { if (err) return callback(err); if (data && data.body) { @@ -3320,7 +3353,7 @@ function _submitRequest(params, callback) { var region = params.Region; var object = params.Key; var method = params.method || 'GET'; - var url = params.url; + var url = params.url || params.Url; var body = params.body; var json = params.json; var rawBody = params.rawBody; @@ -3515,6 +3548,7 @@ var API_MAP = { putObjectTagging: putObjectTagging, getObjectTagging: getObjectTagging, deleteObjectTagging: deleteObjectTagging, + appendObject: appendObject, // 分块上传相关方法 uploadPartCopy: uploadPartCopy, diff --git a/src/ci.js b/src/ci.js new file mode 100644 index 0000000..122e8a5 --- /dev/null +++ b/src/ci.js @@ -0,0 +1,99 @@ +var util = require('./util'); + +/** + * 查询已经开通数据万象功能的存储桶 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ +function describeMediaBuckets(params, callback) { + var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Url: url + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件信息 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getMediaInfo(params, callback) { + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: { + 'ci-process': 'videoinfo' + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +/** + * 获取媒体文件某个时间的截图 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key 文件名称,必须 + * @param {Number} params.Time 截图的时间点,单位为秒,必须 + * @param {Number} params.Width 截图的宽,非必须 + * @param {Number} params.Height 截图的高,非必须 + * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 + * @param {String} params.Rotate 图片旋转方式,非必须 + * @param {String} params.Mode 截帧方式,非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 为对应的 object 数据 + */ + function getSnapshot(params, callback) { + var query = { + 'ci-process': 'snapshot', + time: params.Time || 1, + width: params.Width || 0, + height: params.Height || 0, + format: params.Format || 'jpg', + rotate: params.Rotate || 'auto', + mode: params.Mode || 'exactframe', + }; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: params.Key, + Query: query, + RawBody: true, + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); +} + +var API_MAP = { + describeMediaBuckets: describeMediaBuckets, + getMediaInfo: getMediaInfo, + getSnapshot: getSnapshot, +}; + +module.exports.init = function (COS) { + util.each(API_MAP, function (fn, apiName) { + COS.prototype[apiName] = util.apiWrapper(apiName, fn); + }); +}; \ No newline at end of file diff --git a/src/cos.js b/src/cos.js index 7c7de0b..1ea0faf 100644 --- a/src/cos.js +++ b/src/cos.js @@ -5,6 +5,7 @@ var event = require('./event'); var task = require('./task'); var base = require('./base'); var advance = require('./advance'); +var ci = require('./ci'); var defaultOptions = { SecretId: '', @@ -55,8 +56,9 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); +ci.init(COS); COS.getAuthorization = util.getAuth; -COS.version = '1.0.13'; +COS.version = '1.1.0'; module.exports = COS; diff --git a/src/util.js b/src/util.js index e874f85..ef7256c 100644 --- a/src/util.js +++ b/src/util.js @@ -174,7 +174,7 @@ var getFileMd5 = function (body, callback) { function clone(obj) { return map(obj, function (v) { - return typeof v === 'object' ? clone(v) : v; + return typeof v === 'object' && v !== null ? clone(v) : v; }); } From 8d5571fe498321c18461444abe09d5164287e925 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Sat, 13 Nov 2021 17:52:51 +0800 Subject: [PATCH 02/10] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=A2=9Etest?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E4=B8=8E=E6=B5=8B=E8=AF=95=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/test.js | 77 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/demo/test.js b/demo/test.js index 2fcc7ca..20def80 100644 --- a/demo/test.js +++ b/demo/test.js @@ -1,8 +1,14 @@ var COS = require('./lib/cos-wx-sdk-v5'); var wxfs = wx.getFileSystemManager(); var config = require('./config'); +// 这里替换成自己的Uin (账号ID查询:https://console.cloud.tencent.com/developer) config.Uin = '10001'; +/** + * 测试须知 + * 需要本地准备一个名为 5m.zip,大小为5mb的文件进行初始化上传 +**/ + var util = { createFile: function (options, filePath) { var buffer = new ArrayBuffer(options.size || 0); @@ -364,7 +370,7 @@ group('putObject(),cancelTask()', function () { Bucket: config.Bucket, Region: config.Region, Key: filename, - Body: util.createFile({size: 1024 * 1024 * 100}), + Body: util.createFile({size: 1024 * 1024 * 10}), onTaskReady: function (taskId) { TaskId = taskId; }, @@ -391,8 +397,8 @@ group('putObject(),cancelTask()', function () { group('sliceUploadFile() 完整上传文件', function () { test('sliceUploadFile() 完整上传文件', function (done, assert) { var lastPercent; - var filename = '3m.zip'; - var fileSize = 1024 * 1024 * 3; + var filename = '5m.zip'; + var fileSize = 1024 * 1024 * 5; cos.abortUploadTask({ Bucket: config.Bucket, Region: config.Region, @@ -473,8 +479,8 @@ group('sliceUploadFile(),pauseTask(),restartTask()', function () { group('sliceUploadFile(),cancelTask()', function () { test('sliceUploadFile(),cancelTask()', function (done, assert) { - var filename = '3m.zip'; - var blob = util.createFile({size: 1024 * 1024 * 3}); + var filename = '5m.zip'; + var blob = util.createFile({size: 1024 * 1024 * 5}); var alive = false; var canceled = false; cos.sliceUploadFile({ @@ -2840,3 +2846,64 @@ group('Query 的键值带有特殊字符', function () { }); }); }); + +group('appendObject', function () { + test('describeMediaBuckets()', function (done, assert) { + cos.headObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + }, function(err, data) { + assert.ok(!err); + if (err) return console.log(err); + // 首先取到要追加的文件当前长度,即需要上送的Position + var position = data.headers['content-length']; + cos.appendObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + Body: '66666', + Position: position, + }, + function(err, data) { + assert.ok(!err); + done(); + }) + }); + }); +}); + +group('数据万象', function () { + test('describeMediaBuckets()', function (done, assert) { + cos.describeMediaBuckets({ + Bucket: config.Bucket, + Region: config.Region, + }, + function(err, data){ + assert.ok(!err); + done(); + }); + }); + test('getMediaInfo()', function (done, assert) { + cos.getMediaInfo({ + Bucket: config.Bucket, + Region: config.Region, + Key: '1.mp4', + }, + function(err, data){ + assert.ok(!err); + done(); + }); + }); + test('describeMediaBuckets()', function (done, assert) { + cos.getSnapshot({ + Bucket: config.Bucket, + Region: config.Region, + Key: '1.mp4', + }, + function(err, data){ + assert.ok(!err); + done(); + }); + }); + }); From 4cfb13695cb483d97bc6f95b754c15b09fbc1a33 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 15 Nov 2021 15:42:15 +0800 Subject: [PATCH 03/10] =?UTF-8?q?feat/=E6=94=AF=E6=8C=81appendObject?= =?UTF-8?q?=EF=BC=9B=E6=96=B0=E5=A2=9E=E5=AA=92=E4=BD=93=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=B8=89=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo-album/lib/cos-wx-sdk-v5.js | 82 ++++++++++++++++++++++++--------- demo/demo-sdk.js | 3 ++ demo/lib/cos-wx-sdk-v5.js | 82 ++++++++++++++++++++++++--------- demo/project.config.json | 8 +++- lib/request.js | 1 + src/base.js | 42 +++++++++++++---- src/ci.js | 31 ++++++++----- src/util.js | 8 ++++ 8 files changed, 192 insertions(+), 65 deletions(-) diff --git a/demo-album/lib/cos-wx-sdk-v5.js b/demo-album/lib/cos-wx-sdk-v5.js index 7490658..8ae2092 100644 --- a/demo-album/lib/cos-wx-sdk-v5.js +++ b/demo-album/lib/cos-wx-sdk-v5.js @@ -629,6 +629,13 @@ var canFileSlice = (function () { }; })(); +var isCiHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false +} + var util = { noop: noop, formatParams: formatParams, @@ -659,6 +666,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, + isCiHost: isCiHost, }; module.exports = util; @@ -8102,15 +8110,31 @@ function multipartAbort(params, callback) { /** * 追加上传 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key object名称,必须 - * @param {File || Blob || String} params.Body 上传文件对象或字符串 - * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 返回的数据 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {String} params.Body 上传文件的内容,只支持字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须 + * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须 + * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须 + * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须 + * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须 + * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须 + * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须 + * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须 + * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 */ function appendObject(params, callback) { submitRequest.call(this, { @@ -8689,12 +8713,18 @@ function _submitRequest(params, callback) { json: json, }; + // 兼容ci接口 + var token = 'x-cos-security-token'; + if (util.isCiHost(url)) { + token = 'x-ci-security-token'; + } + // 获取签名 opt.headers.Authorization = params.AuthData.Authorization; params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token); params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP); params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA); - params.AuthData.XCosSecurityToken && (opt.headers['x-cos-security-token'] = params.AuthData.XCosSecurityToken); + params.AuthData.XCosSecurityToken && (opt.headers[token] = params.AuthData.XCosSecurityToken); // 清理 undefined 和 null 字段 opt.headers && (opt.headers = util.clearKey(opt.headers)); @@ -8967,6 +8997,7 @@ var request = function (params, callback) { 'Expires', 'x-cos-storage-class', 'x-cos-security-token', + 'x-ci-security-token', ]; for (var i in params.headers) { if (params.headers.hasOwnProperty(i) && (i.indexOf('x-cos-meta-') > -1 || headerKeys.indexOf(i) > -1)) { @@ -10440,17 +10471,26 @@ var util = __webpack_require__(0); * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 * @return {Object} data 为对应的 object 数据 */ -function describeMediaBuckets(params, callback) { - var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Url: url - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); + function describeMediaBuckets(params, callback) { + var host = 'ci.' + params.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: 'mediabucket', + Url: url, + Query: { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); } /** diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index 7f68e7c..94e8007 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -663,6 +663,9 @@ var dao = { cos.describeMediaBuckets({ Bucket: config.Bucket, Region: config.Region, + Regions: 'ap-chengdu', + // BucketNames: 'test1-1250000000,test2-1250000000', // 筛选存储桶名为test1-1250000000,test2-1250000000 + BucketName: 'test', // 筛选bucket前缀为test的存储桶 }, function(err, data){ console.log(err || data); diff --git a/demo/lib/cos-wx-sdk-v5.js b/demo/lib/cos-wx-sdk-v5.js index 7490658..8ae2092 100644 --- a/demo/lib/cos-wx-sdk-v5.js +++ b/demo/lib/cos-wx-sdk-v5.js @@ -629,6 +629,13 @@ var canFileSlice = (function () { }; })(); +var isCiHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false +} + var util = { noop: noop, formatParams: formatParams, @@ -659,6 +666,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, + isCiHost: isCiHost, }; module.exports = util; @@ -8102,15 +8110,31 @@ function multipartAbort(params, callback) { /** * 追加上传 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key object名称,必须 - * @param {File || Blob || String} params.Body 上传文件对象或字符串 - * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 返回的数据 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {String} params.Body 上传文件的内容,只支持字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须 + * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须 + * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须 + * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须 + * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须 + * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须 + * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须 + * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须 + * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 */ function appendObject(params, callback) { submitRequest.call(this, { @@ -8689,12 +8713,18 @@ function _submitRequest(params, callback) { json: json, }; + // 兼容ci接口 + var token = 'x-cos-security-token'; + if (util.isCiHost(url)) { + token = 'x-ci-security-token'; + } + // 获取签名 opt.headers.Authorization = params.AuthData.Authorization; params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token); params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP); params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA); - params.AuthData.XCosSecurityToken && (opt.headers['x-cos-security-token'] = params.AuthData.XCosSecurityToken); + params.AuthData.XCosSecurityToken && (opt.headers[token] = params.AuthData.XCosSecurityToken); // 清理 undefined 和 null 字段 opt.headers && (opt.headers = util.clearKey(opt.headers)); @@ -8967,6 +8997,7 @@ var request = function (params, callback) { 'Expires', 'x-cos-storage-class', 'x-cos-security-token', + 'x-ci-security-token', ]; for (var i in params.headers) { if (params.headers.hasOwnProperty(i) && (i.indexOf('x-cos-meta-') > -1 || headerKeys.indexOf(i) > -1)) { @@ -10440,17 +10471,26 @@ var util = __webpack_require__(0); * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 * @return {Object} data 为对应的 object 数据 */ -function describeMediaBuckets(params, callback) { - var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Url: url - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); + function describeMediaBuckets(params, callback) { + var host = 'ci.' + params.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: 'mediabucket', + Url: url, + Query: { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); } /** diff --git a/demo/project.config.json b/demo/project.config.json index 42494af..674c38c 100644 --- a/demo/project.config.json +++ b/demo/project.config.json @@ -18,18 +18,22 @@ "checkSiteMap": true, "uploadWithSourceMap": true, "compileHotReLoad": false, - "useMultiFrameRuntime": false, + "useMultiFrameRuntime": true, "useApiHook": true, + "useApiHostProcess": true, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" }, + "enableEngineNative": false, "useIsolateContext": true, "useCompilerModule": true, "userConfirmedUseCompilerModuleSwitch": false, + "userConfirmedBundleSwitch": false, "packNpmManually": false, - "packNpmRelationList": [] + "packNpmRelationList": [], + "minifyWXSS": true }, "compileType": "miniprogram", "libVersion": "1.6.0", diff --git a/lib/request.js b/lib/request.js index 0668d32..378ca9a 100644 --- a/lib/request.js +++ b/lib/request.js @@ -89,6 +89,7 @@ var request = function (params, callback) { 'Expires', 'x-cos-storage-class', 'x-cos-security-token', + 'x-ci-security-token', ]; for (var i in params.headers) { if (params.headers.hasOwnProperty(i) && (i.indexOf('x-cos-meta-') > -1 || headerKeys.indexOf(i) > -1)) { diff --git a/src/base.js b/src/base.js index 71db3ce..03364e4 100644 --- a/src/base.js +++ b/src/base.js @@ -2804,15 +2804,31 @@ function multipartAbort(params, callback) { /** * 追加上传 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key object名称,必须 - * @param {File || Blob || String} params.Body 上传文件对象或字符串 - * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 返回的数据 + * @param {Object} params 参数对象,必须 + * @param {String} params.Bucket Bucket名称,必须 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.Key object名称,必须 + * @param {String} params.Body 上传文件的内容,只支持字符串 + * @param {Number} params.Position 追加操作的起始点,单位为字节,必须 + * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须 + * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须 + * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须 + * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须 + * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须 + * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须 + * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须 + * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须 + * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须 + * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须 + * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须 + * @param {Function} callback 回调函数,必须 + * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 + * @return {Object} data 返回的数据 */ function appendObject(params, callback) { submitRequest.call(this, { @@ -3391,12 +3407,18 @@ function _submitRequest(params, callback) { json: json, }; + // 兼容ci接口 + var token = 'x-cos-security-token'; + if (util.isCiHost(url)) { + token = 'x-ci-security-token'; + } + // 获取签名 opt.headers.Authorization = params.AuthData.Authorization; params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token); params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP); params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA); - params.AuthData.XCosSecurityToken && (opt.headers['x-cos-security-token'] = params.AuthData.XCosSecurityToken); + params.AuthData.XCosSecurityToken && (opt.headers[token] = params.AuthData.XCosSecurityToken); // 清理 undefined 和 null 字段 opt.headers && (opt.headers = util.clearKey(opt.headers)); diff --git a/src/ci.js b/src/ci.js index 122e8a5..f55f4d5 100644 --- a/src/ci.js +++ b/src/ci.js @@ -9,17 +9,26 @@ var util = require('./util'); * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 * @return {Object} data 为对应的 object 数据 */ -function describeMediaBuckets(params, callback) { - var url = 'https://' + params.Bucket + '.pic.' + params.Region + '.myqcloud.com'; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Url: url - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); + function describeMediaBuckets(params, callback) { + var host = 'ci.' + params.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: 'mediabucket', + Url: url, + Query: { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + } + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); } /** diff --git a/src/util.js b/src/util.js index ef7256c..c0541ce 100644 --- a/src/util.js +++ b/src/util.js @@ -549,6 +549,13 @@ var canFileSlice = (function () { }; })(); +var isCiHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false +} + var util = { noop: noop, formatParams: formatParams, @@ -579,6 +586,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, + isCiHost: isCiHost, }; module.exports = util; From f16699f55b40ba721060cdc52de1ef0c8a71d8a8 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 15 Nov 2021 16:06:33 +0800 Subject: [PATCH 04/10] =?UTF-8?q?feat=EF=BC=9Ademo=E6=95=B4=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/demo-sdk.js | 186 ++++++++++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 75 deletions(-) diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index 0e10379..e6b890e 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -213,7 +213,7 @@ var toolsDao = { } }); }, - '分片上传': function() { + 'sliceUploadFile 分片上传': function() { var sliceUploadFile = function (file) { var key = file.name; cos.sliceUploadFile({ @@ -341,7 +341,7 @@ var toolsDao = { Body: fileBuf, }, requestCallback); }, - getObjectUrl: function() { + 'getObjectUrl 获取对象访问url': function() { var url = cos.getObjectUrl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, @@ -361,44 +361,44 @@ var bucketDao = { cos.getService(requestCallback); }, // 简单 Bucket 操作 - putBucket: function() { + 'putBucket 创建存储桶': function() { cos.putBucket({ Bucket: config.Bucket, Region: config.Region, }, requestCallback); }, - headBucket: function() { + 'headBucket 检索存储桶及其权限': function() { cos.headBucket({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - deleteBucket: function() { + 'deleteBucket 删除存储桶': function() { cos.deleteBucket({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - getBucketACL: function() { + 'getBucketACL 查询存储桶 ACL': function() { cos.getBucketAcl({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - putBucketACL: function() { + 'putBucketACL 设置存储桶 ACL': function() { cos.putBucketAcl({ Bucket: config.Bucket, Region: config.Region, ACL: 'public-read' }, requestCallback); }, - getBucketCors: function() { + 'getBucketCors 查询跨域配置': function() { cos.getBucketCors({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - putBucketCors: function() { + 'putBucketCors 设置跨域配置': function() { cos.putBucketCors({ Bucket: config.Bucket, Region: config.Region, @@ -411,13 +411,13 @@ var bucketDao = { }] }, requestCallback); }, - deleteBucketCors: function() { + 'deleteBucketCors 删除跨域配置': function() { cos.deleteBucketCors({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - putBucketPolicy: function() { + 'putBucketPolicy 设置存储桶策略': function() { var AppId = config.Bucket.substr(config.Bucket.lastIndexOf('-') + 1); cos.putBucketPolicy({ Bucket: config.Bucket, @@ -447,31 +447,31 @@ var bucketDao = { }, }, requestCallback); }, - getBucketPolicy: function() { + 'getBucketPolicy 查询存储桶策略': function() { cos.getBucketPolicy({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - deleteBucketPolicy: function() { + 'deleteBucketPolicy 删除存储桶策略': function() { cos.deleteBucketPolicy({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - getBucketLocation: function() { + 'getBucketLocation 获取Bucket的地域信息': function() { cos.getBucketLocation({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - getBucketTagging: function() { + 'getBucketTagging 获取Bucket标签': function() { cos.getBucketTagging({ Bucket: config.Bucket, Region: config.Region }, requestCallback); }, - putBucketTagging: function() { + 'putBucketTagging 设置Bucket标签': function() { cos.putBucketTagging({ Bucket: config.Bucket, Region: config.Region, @@ -489,7 +489,7 @@ var bucketDao = { } }, requestCallback); }, - deleteBucketTagging: function() { + 'deleteBucketTagging 删除存储桶标签': function() { cos.deleteBucketTagging({ Bucket: config.Bucket, Region: config.Region @@ -581,7 +581,7 @@ var objectDao = { Body: fileBuf, }, requestCallback); }, - getObject: function() { + 'getObject 下载对象': function() { cos.getObject({ Bucket: config.Bucket, Region: config.Region, @@ -590,28 +590,28 @@ var objectDao = { // QueryString: `imageMogr2/thumbnail/200x/`, }, requestCallback); }, - headObject: function() { + 'headObject 检索对象': function() { cos.headObject({ Bucket: config.Bucket, Region: config.Region, Key: '1.txt' }, requestCallback); }, - deleteObject: function() { + 'deleteObject 删除对象': function() { cos.deleteObject({ Bucket: config.Bucket, Region: config.Region, Key: '1.txt' }, requestCallback); }, - getObjectACL: function() { + 'getObjectACL 获取对象ACL': function() { cos.getObjectAcl({ Bucket: config.Bucket, Region: config.Region, Key: '1.txt' }, requestCallback); }, - putObjectACL: function() { + 'putObjectACL 设置对象ACL': function() { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, @@ -636,7 +636,7 @@ var objectDao = { // } }, requestCallback); }, - deleteMultipleObject: function() { + 'deleteMultipleObject 批量删除对象': function() { cos.deleteMultipleObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, @@ -649,7 +649,7 @@ var objectDao = { ] }, requestCallback); }, - putObjectCopy: function() { + 'putObjectCopy 复制对象': function() { cos.putObjectCopy({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, @@ -657,7 +657,7 @@ var objectDao = { CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/1.txt', }, requestCallback); }, - restoreObject: function() { + 'restoreObject 恢复归档对象': function() { cos.restoreObject({ Bucket: config.Bucket, Region: config.Region, @@ -670,27 +670,64 @@ var objectDao = { } }, requestCallback); }, - abortUploadTask: function() { - cos.abortUploadTask({ - Bucket: config.Bucket, - /* 必须 */ // Bucket 格式:test-1250000000 + 'appendObject 追加上传': function() { + // 初始化一个可追加上传的对象append.txt + cos.appendObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, - /* 必须 */ - // 格式1,删除单个上传任务 - // Level: 'task', - // Key: '10mb.zip', - // UploadId: '14985543913e4e2642e31db217b9a1a3d9b3cd6cf62abfda23372c8d36ffa38585492681e3', - // 格式2,删除单个文件所有未完成上传任务 - Level: 'file', - Key: '10mb.zip', - // 格式3,删除 Bucket 下所有未完成上传任务 - // Level: 'bucket', - }, requestCallback); + Key: 'append.txt', /* 必须 */ + Body: '12345', + Position: 0, + }, + function(err, data) { + logger.log('putObject:', err || data); + }) }, + 'appendObject_continue 继续追加上传': function() { + // append.txt必须是一个可追加上传的对象,参考文档:https://cloud.tencent.com/document/product/436/7741 + cos.headObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + }, function(err, data) { + if (err) return console.log(err); + // 首先取到要追加的文件当前长度,即需要上送的Position + var position = data.headers['content-length']; + cos.appendObject({ + Bucket: config.Bucket, // Bucket 格式:test-1250000000 + Region: config.Region, + Key: 'append.txt', /* 必须 */ + Body: '66666', + Position: position, + }, + function(err, data) { + // 也可以取到下一次上传的position继续追加上传 + // var nextPosition = data.headers['x-cos-next-append-position']; + logger.log('putObject:', err || data); + }) + }); + } + // abortUploadTask: function() { + // cos.abortUploadTask({ + // Bucket: config.Bucket, + // /* 必须 */ // Bucket 格式:test-1250000000 + // Region: config.Region, + // /* 必须 */ + // // 格式1,删除单个上传任务 + // // Level: 'task', + // // Key: '10mb.zip', + // // UploadId: '14985543913e4e2642e31db217b9a1a3d9b3cd6cf62abfda23372c8d36ffa38585492681e3', + // // 格式2,删除单个文件所有未完成上传任务 + // Level: 'file', + // Key: '10mb.zip', + // // 格式3,删除 Bucket 下所有未完成上传任务 + // // Level: 'bucket', + // }, requestCallback); + // }, } var advanceObjectDao = { - 'sliceUploadFile 分片上传': function() { + 'sliceUploadFile 分块上传': function() { var sliceUploadFile = function (file) { var key = file.name; cos.sliceUploadFile({ @@ -741,7 +778,7 @@ var advanceObjectDao = { // } // }) }, - 'sliceCopyFile 分片复制': function() { + 'sliceCopyFile 分块复制对象': function() { // 创建测试文件 var sourceName = '1.txt'; var Key = '1.slicecopy.exe'; @@ -761,38 +798,6 @@ var advanceObjectDao = { } }, requestCallback); }, - describeMediaBuckets: function() { - cos.describeMediaBuckets({ - Bucket: config.Bucket, - Region: config.Region, - Regions: 'ap-chengdu', - // BucketNames: 'test1-1250000000,test2-1250000000', // 筛选存储桶名为test1-1250000000,test2-1250000000 - BucketName: 'test', // 筛选bucket前缀为test的存储桶 - }, - function(err, data){ - console.log(err || data); - }); - }, - getMediaInfo: function() { - cos.getMediaInfo({ - Bucket: config.Bucket, - Region: config.Region, - Key: '20.mp4', - }, - function(err, data){ - console.log(err || data); - }); - }, - getSnapshot: function() { - cos.getSnapshot({ - Bucket: config.Bucket, - Region: config.Region, - Key: '20.mp4', - }, - function(err, data){ - console.log(err || data); - }); - }, cancelTask: function() { cos.cancelTask(TaskId); console.log('canceled'); @@ -884,7 +889,38 @@ var ciObjectDao = { (err, data) => { console.log('不带签名', err || data); }); - + }, + 'describeMediaBuckets 查询已经开通数据万象功能的存储桶': function() { + cos.describeMediaBuckets({ + Bucket: config.Bucket, + Region: config.Region, + Regions: 'ap-chengdu', + // BucketNames: 'test1-1250000000,test2-1250000000', // 筛选存储桶名为test1-1250000000,test2-1250000000 + BucketName: 'test', // 筛选bucket前缀为test的存储桶 + }, + function(err, data){ + console.log(err || data); + }); + }, + 'getMediaInfo 获取媒体文件信息': function() { + cos.getMediaInfo({ + Bucket: config.Bucket, + Region: config.Region, + Key: '1.mp4', + }, + function(err, data){ + console.log(err || data); + }); + }, + 'getSnapshot 获取媒体文件某个时间的截图': function() { + cos.getSnapshot({ + Bucket: config.Bucket, + Region: config.Region, + Key: '1.mp4', + }, + function(err, data){ + console.log(err || data); + }); }, } From b84d3fc0a95645486a5dc227e9c67c11de0d3a85 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 15 Nov 2021 16:14:49 +0800 Subject: [PATCH 05/10] upd --- demo-album/lib/cos-wx-sdk-v5.js | 15 ++++++++------- demo/demo-sdk.js | 4 ++-- demo/lib/cos-wx-sdk-v5.js | 15 ++++++++------- src/ci.js | 15 ++++++++------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/demo-album/lib/cos-wx-sdk-v5.js b/demo-album/lib/cos-wx-sdk-v5.js index 8ae2092..dbe25a4 100644 --- a/demo-album/lib/cos-wx-sdk-v5.js +++ b/demo-album/lib/cos-wx-sdk-v5.js @@ -10474,19 +10474,20 @@ var util = __webpack_require__(0); function describeMediaBuckets(params, callback) { var host = 'ci.' + params.Region + '.myqcloud.com'; var url = 'https://' + host + '/mediabucket'; + var query = { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + }; this.request({ Bucket: params.Bucket, Region: params.Region, Method: 'GET', Key: 'mediabucket', Url: url, - Query: { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - } + Query: query }, function (err, data) { if (err) return callback(err); callback(null, data); diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index e6b890e..a514b0f 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -894,9 +894,9 @@ var ciObjectDao = { cos.describeMediaBuckets({ Bucket: config.Bucket, Region: config.Region, - Regions: 'ap-chengdu', + Regions: 'ap-chengdu', // 筛选成都地域的bucket // BucketNames: 'test1-1250000000,test2-1250000000', // 筛选存储桶名为test1-1250000000,test2-1250000000 - BucketName: 'test', // 筛选bucket前缀为test的存储桶 + // BucketName: 'test', // 筛选bucket前缀为test的存储桶 }, function(err, data){ console.log(err || data); diff --git a/demo/lib/cos-wx-sdk-v5.js b/demo/lib/cos-wx-sdk-v5.js index 8ae2092..dbe25a4 100644 --- a/demo/lib/cos-wx-sdk-v5.js +++ b/demo/lib/cos-wx-sdk-v5.js @@ -10474,19 +10474,20 @@ var util = __webpack_require__(0); function describeMediaBuckets(params, callback) { var host = 'ci.' + params.Region + '.myqcloud.com'; var url = 'https://' + host + '/mediabucket'; + var query = { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + }; this.request({ Bucket: params.Bucket, Region: params.Region, Method: 'GET', Key: 'mediabucket', Url: url, - Query: { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - } + Query: query }, function (err, data) { if (err) return callback(err); callback(null, data); diff --git a/src/ci.js b/src/ci.js index f55f4d5..fa11fcf 100644 --- a/src/ci.js +++ b/src/ci.js @@ -12,19 +12,20 @@ var util = require('./util'); function describeMediaBuckets(params, callback) { var host = 'ci.' + params.Region + '.myqcloud.com'; var url = 'https://' + host + '/mediabucket'; + var query = { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + }; this.request({ Bucket: params.Bucket, Region: params.Region, Method: 'GET', Key: 'mediabucket', Url: url, - Query: { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - } + Query: query }, function (err, data) { if (err) return callback(err); callback(null, data); From dfe356de86c5c04abb46f6758bd90aad0bfcbc99 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 15 Nov 2021 17:46:15 +0800 Subject: [PATCH 06/10] upd --- src/base.js | 2 +- src/ci.js | 77 ++++++++++++++++++++++++++++------------------------- src/util.js | 12 ++++----- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/base.js b/src/base.js index 03364e4..b7cee82 100644 --- a/src/base.js +++ b/src/base.js @@ -3409,7 +3409,7 @@ function _submitRequest(params, callback) { // 兼容ci接口 var token = 'x-cos-security-token'; - if (util.isCiHost(url)) { + if (util.isCIHost(url)) { token = 'x-ci-security-token'; } diff --git a/src/ci.js b/src/ci.js index fa11fcf..d2a1781 100644 --- a/src/ci.js +++ b/src/ci.js @@ -3,33 +3,38 @@ var util = require('./util'); /** * 查询已经开通数据万象功能的存储桶 * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {Function} callback 回调函数,必须 + * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 + * @param {String} params.Region 地域名称,必须 + * @param {String} params.PageNumber 第几页,非必须 + * @param {String} params.PageSize 每页个数,非必须 + * @param {String} params.Regions 地域信息,例如'ap-shanghai,ap-beijing',非必须 + * @param {String} params.BucketNames 存储桶名称,以“,”分隔,支持多个存储桶,精确搜索,非必须 + * @param {String} params.BucketName 存储桶名称前缀,前缀搜索,非必须 + * @param {Function} callback 回调函数,必须 * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 * @return {Object} data 为对应的 object 数据 */ function describeMediaBuckets(params, callback) { - var host = 'ci.' + params.Region + '.myqcloud.com'; - var url = 'https://' + host + '/mediabucket'; - var query = { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: 'mediabucket', - Url: url, - Query: query - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); + var host = 'ci.' + params.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + var query = { + pageNumber: params.PageNumber, + pageSize: params.PageSize, + regions: params.Regions, + bucketNames: params.BucketNames, + bucketName: params.BucketName, + }; + this.request({ + Bucket: params.Bucket, + Region: params.Region, + Method: 'GET', + Key: 'mediabucket', + Url: url, + Query: query + }, function (err, data) { + if (err) return callback(err); + callback(null, data); + }); } /** @@ -75,13 +80,13 @@ var util = require('./util'); */ function getSnapshot(params, callback) { var query = { - 'ci-process': 'snapshot', - time: params.Time || 1, - width: params.Width || 0, - height: params.Height || 0, - format: params.Format || 'jpg', - rotate: params.Rotate || 'auto', - mode: params.Mode || 'exactframe', + 'ci-process': 'snapshot', + time: params.Time || 1, + width: params.Width || 0, + height: params.Height || 0, + format: params.Format || 'jpg', + rotate: params.Rotate || 'auto', + mode: params.Mode || 'exactframe', }; this.request({ Bucket: params.Bucket, @@ -97,13 +102,13 @@ var util = require('./util'); } var API_MAP = { - describeMediaBuckets: describeMediaBuckets, - getMediaInfo: getMediaInfo, - getSnapshot: getSnapshot, + describeMediaBuckets: describeMediaBuckets, + getMediaInfo: getMediaInfo, + getSnapshot: getSnapshot, }; module.exports.init = function (COS) { - util.each(API_MAP, function (fn, apiName) { - COS.prototype[apiName] = util.apiWrapper(apiName, fn); - }); + util.each(API_MAP, function (fn, apiName) { + COS.prototype[apiName] = util.apiWrapper(apiName, fn); + }); }; \ No newline at end of file diff --git a/src/util.js b/src/util.js index c0541ce..b8d20da 100644 --- a/src/util.js +++ b/src/util.js @@ -549,11 +549,11 @@ var canFileSlice = (function () { }; })(); -var isCiHost = function(url) { - if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { - return true; - } - return false +var isCIHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false; } var util = { @@ -586,7 +586,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, - isCiHost: isCiHost, + isCIHost: isCIHost, }; module.exports = util; From f22ce39ec68ad0732b4a9b06ec86edd2efe5328e Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 15 Nov 2021 18:12:51 +0800 Subject: [PATCH 07/10] =?UTF-8?q?upd=EF=BC=9Atest.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/test.js b/demo/test.js index 20def80..75b8bc6 100644 --- a/demo/test.js +++ b/demo/test.js @@ -2848,7 +2848,7 @@ group('Query 的键值带有特殊字符', function () { }); group('appendObject', function () { - test('describeMediaBuckets()', function (done, assert) { + test('appendObject()', function (done, assert) { cos.headObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, @@ -2888,7 +2888,7 @@ group('数据万象', function () { cos.getMediaInfo({ Bucket: config.Bucket, Region: config.Region, - Key: '1.mp4', + Key: 'test.mp4', }, function(err, data){ assert.ok(!err); @@ -2899,7 +2899,7 @@ group('数据万象', function () { cos.getSnapshot({ Bucket: config.Bucket, Region: config.Region, - Key: '1.mp4', + Key: 'test.mp4', }, function(err, data){ assert.ok(!err); From 8f87f31b232b2f5e04c44609371c3f9a0829cf69 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Tue, 16 Nov 2021 15:39:29 +0800 Subject: [PATCH 08/10] =?UTF-8?q?upd=EF=BC=9A=E6=94=AF=E6=8C=81ci=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo-album/lib/cos-wx-sdk-v5.js | 130 ++------------------------------ demo/demo-sdk.js | 39 ++++++++-- demo/lib/cos-wx-sdk-v5.js | 130 ++------------------------------ demo/test.js | 36 +++++++-- src/ci.js | 114 ---------------------------- src/cos.js | 2 - 6 files changed, 76 insertions(+), 375 deletions(-) delete mode 100644 src/ci.js diff --git a/demo-album/lib/cos-wx-sdk-v5.js b/demo-album/lib/cos-wx-sdk-v5.js index dbe25a4..89302e7 100644 --- a/demo-album/lib/cos-wx-sdk-v5.js +++ b/demo-album/lib/cos-wx-sdk-v5.js @@ -629,11 +629,11 @@ var canFileSlice = (function () { }; })(); -var isCiHost = function(url) { - if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { - return true; - } - return false +var isCIHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false; } var util = { @@ -666,7 +666,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, - isCiHost: isCiHost, + isCIHost: isCIHost, }; module.exports = util; @@ -2295,7 +2295,6 @@ var event = __webpack_require__(4); var task = __webpack_require__(16); var base = __webpack_require__(17); var advance = __webpack_require__(23); -var ci = __webpack_require__(25); var defaultOptions = { SecretId: '', @@ -2346,7 +2345,6 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); -ci.init(COS); COS.getAuthorization = util.getAuth; COS.version = '1.1.0'; @@ -8715,7 +8713,7 @@ function _submitRequest(params, callback) { // 兼容ci接口 var token = 'x-cos-security-token'; - if (util.isCiHost(url)) { + if (util.isCIHost(url)) { token = 'x-ci-security-token'; } @@ -10456,120 +10454,6 @@ var async = { module.exports = async; -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -var util = __webpack_require__(0); - -/** - * 查询已经开通数据万象功能的存储桶 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function describeMediaBuckets(params, callback) { - var host = 'ci.' + params.Region + '.myqcloud.com'; - var url = 'https://' + host + '/mediabucket'; - var query = { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: 'mediabucket', - Url: url, - Query: query - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件信息 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getMediaInfo(params, callback) { - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: { - 'ci-process': 'videoinfo' - } - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件某个时间的截图 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Number} params.Time 截图的时间点,单位为秒,必须 - * @param {Number} params.Width 截图的宽,非必须 - * @param {Number} params.Height 截图的高,非必须 - * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 - * @param {String} params.Rotate 图片旋转方式,非必须 - * @param {String} params.Mode 截帧方式,非必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getSnapshot(params, callback) { - var query = { - 'ci-process': 'snapshot', - time: params.Time || 1, - width: params.Width || 0, - height: params.Height || 0, - format: params.Format || 'jpg', - rotate: params.Rotate || 'auto', - mode: params.Mode || 'exactframe', - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: query, - RawBody: true, - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -var API_MAP = { - describeMediaBuckets: describeMediaBuckets, - getMediaInfo: getMediaInfo, - getSnapshot: getSnapshot, -}; - -module.exports.init = function (COS) { - util.each(API_MAP, function (fn, apiName) { - COS.prototype[apiName] = util.apiWrapper(apiName, fn); - }); -}; - /***/ }) /******/ ]); }); \ No newline at end of file diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index a514b0f..58401ab 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -891,32 +891,55 @@ var ciObjectDao = { }); }, 'describeMediaBuckets 查询已经开通数据万象功能的存储桶': function() { - cos.describeMediaBuckets({ + var host = 'ci.' + config.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + cos.request({ Bucket: config.Bucket, Region: config.Region, - Regions: 'ap-chengdu', // 筛选成都地域的bucket - // BucketNames: 'test1-1250000000,test2-1250000000', // 筛选存储桶名为test1-1250000000,test2-1250000000 - // BucketName: 'test', // 筛选bucket前缀为test的存储桶 + Method: 'GET', + Key: 'mediabucket', /** 固定值,必须 */ + Url: url, + Query: { + pageNumber: '1', /** 第几页,非必须 */ + pageSize: '10', /** 每页个数,非必须 */ + // regions: 'ap-chengdu', /** 地域信息,例如'ap-beijing',支持多个值用逗号分隔如'ap-shanghai,ap-beijing',非必须 */ + // bucketNames: 'test-1250000000', /** 存储桶名称,精确搜索,例如'test-1250000000',支持多个值用逗号分隔如'test1-1250000000,test2-1250000000',非必须 */ + // bucketName: 'test', /** 存储桶名称前缀,前缀搜索,例如'test',支持多个值用逗号分隔如'test1,test2',非必须 */ + } }, function(err, data){ console.log(err || data); }); }, 'getMediaInfo 获取媒体文件信息': function() { - cos.getMediaInfo({ + cos.request({ Bucket: config.Bucket, Region: config.Region, - Key: '1.mp4', + Method: 'GET', + Key: 'test.mp4', + Query: { + 'ci-process': 'videoinfo' /** 固定值,必须 */ + } }, function(err, data){ console.log(err || data); }); }, 'getSnapshot 获取媒体文件某个时间的截图': function() { - cos.getSnapshot({ + cos.request({ Bucket: config.Bucket, Region: config.Region, - Key: '1.mp4', + Key: 'test.mp4', + Query: { + 'ci-process': 'snapshot', /** 固定值,必须 */ + time: 1, /** 截图的时间点,单位为秒,必须 */ + // width: 0, /** 截图的宽,非必须 */ + // height: 0, /** 截图的高,非必须 */ + // format: 'jpg', /** 截图的格式,支持 jpg 和 png,默认 jpg,非必须 */ + // rotate: 'auto', /** 图片旋转方式,默认为'auto',非必须 */ + // mode: 'exactframe', /** 截帧方式,默认为'exactframe',非必须 */ + }, + RawBody: true, }, function(err, data){ console.log(err || data); diff --git a/demo/lib/cos-wx-sdk-v5.js b/demo/lib/cos-wx-sdk-v5.js index dbe25a4..89302e7 100644 --- a/demo/lib/cos-wx-sdk-v5.js +++ b/demo/lib/cos-wx-sdk-v5.js @@ -629,11 +629,11 @@ var canFileSlice = (function () { }; })(); -var isCiHost = function(url) { - if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { - return true; - } - return false +var isCIHost = function(url) { + if (url && url.split('?')[0].match(/(.ci.|ci.|.ci)/g)) { + return true; + } + return false; } var util = { @@ -666,7 +666,7 @@ var util = { getAuth: getAuth, compareVersion: compareVersion, canFileSlice: canFileSlice, - isCiHost: isCiHost, + isCIHost: isCIHost, }; module.exports = util; @@ -2295,7 +2295,6 @@ var event = __webpack_require__(4); var task = __webpack_require__(16); var base = __webpack_require__(17); var advance = __webpack_require__(23); -var ci = __webpack_require__(25); var defaultOptions = { SecretId: '', @@ -2346,7 +2345,6 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); -ci.init(COS); COS.getAuthorization = util.getAuth; COS.version = '1.1.0'; @@ -8715,7 +8713,7 @@ function _submitRequest(params, callback) { // 兼容ci接口 var token = 'x-cos-security-token'; - if (util.isCiHost(url)) { + if (util.isCIHost(url)) { token = 'x-ci-security-token'; } @@ -10456,120 +10454,6 @@ var async = { module.exports = async; -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -var util = __webpack_require__(0); - -/** - * 查询已经开通数据万象功能的存储桶 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function describeMediaBuckets(params, callback) { - var host = 'ci.' + params.Region + '.myqcloud.com'; - var url = 'https://' + host + '/mediabucket'; - var query = { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: 'mediabucket', - Url: url, - Query: query - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件信息 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getMediaInfo(params, callback) { - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: { - 'ci-process': 'videoinfo' - } - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件某个时间的截图 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Number} params.Time 截图的时间点,单位为秒,必须 - * @param {Number} params.Width 截图的宽,非必须 - * @param {Number} params.Height 截图的高,非必须 - * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 - * @param {String} params.Rotate 图片旋转方式,非必须 - * @param {String} params.Mode 截帧方式,非必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getSnapshot(params, callback) { - var query = { - 'ci-process': 'snapshot', - time: params.Time || 1, - width: params.Width || 0, - height: params.Height || 0, - format: params.Format || 'jpg', - rotate: params.Rotate || 'auto', - mode: params.Mode || 'exactframe', - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: query, - RawBody: true, - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -var API_MAP = { - describeMediaBuckets: describeMediaBuckets, - getMediaInfo: getMediaInfo, - getSnapshot: getSnapshot, -}; - -module.exports.init = function (COS) { - util.each(API_MAP, function (fn, apiName) { - COS.prototype[apiName] = util.apiWrapper(apiName, fn); - }); -}; - /***/ }) /******/ ]); }); \ No newline at end of file diff --git a/demo/test.js b/demo/test.js index 75b8bc6..dc7a470 100644 --- a/demo/test.js +++ b/demo/test.js @@ -2875,9 +2875,21 @@ group('appendObject', function () { group('数据万象', function () { test('describeMediaBuckets()', function (done, assert) { - cos.describeMediaBuckets({ - Bucket: config.Bucket, - Region: config.Region, + var host = 'ci.' + config.Region + '.myqcloud.com'; + var url = 'https://' + host + '/mediabucket'; + cos.request({ + Bucket: config.Bucket, + Region: config.Region, + Method: 'GET', + Key: 'mediabucket', /** 固定值,必须 */ + Url: url, + Query: { + pageNumber: '1', /** 第几页,非必须 */ + pageSize: '10', /** 每页个数,非必须 */ + // regions: 'ap-chengdu', /** 地域信息,例如'ap-beijing',支持多个值用逗号分隔如'ap-shanghai,ap-beijing',非必须 */ + // bucketNames: 'test-1250000000', /** 存储桶名称,精确搜索,例如'test-1250000000',支持多个值用逗号分隔如'test1-1250000000,test2-1250000000',非必须 */ + // bucketName: 'test', /** 存储桶名称前缀,前缀搜索,例如'test',支持多个值用逗号分隔如'test1,test2',非必须 */ + } }, function(err, data){ assert.ok(!err); @@ -2885,10 +2897,14 @@ group('数据万象', function () { }); }); test('getMediaInfo()', function (done, assert) { - cos.getMediaInfo({ + cos.request({ Bucket: config.Bucket, Region: config.Region, + Method: 'GET', Key: 'test.mp4', + Query: { + 'ci-process': 'videoinfo' /** 固定值,必须 */ + } }, function(err, data){ assert.ok(!err); @@ -2896,10 +2912,20 @@ group('数据万象', function () { }); }); test('describeMediaBuckets()', function (done, assert) { - cos.getSnapshot({ + cos.request({ Bucket: config.Bucket, Region: config.Region, Key: 'test.mp4', + Query: { + 'ci-process': 'snapshot', /** 固定值,必须 */ + time: 1, /** 截图的时间点,单位为秒,必须 */ + // width: 0, /** 截图的宽,非必须 */ + // height: 0, /** 截图的高,非必须 */ + // format: 'jpg', /** 截图的格式,支持 jpg 和 png,默认 jpg,非必须 */ + // rotate: 'auto', /** 图片旋转方式,默认为'auto',非必须 */ + // mode: 'exactframe', /** 截帧方式,默认为'exactframe',非必须 */ + }, + RawBody: true, }, function(err, data){ assert.ok(!err); diff --git a/src/ci.js b/src/ci.js deleted file mode 100644 index d2a1781..0000000 --- a/src/ci.js +++ /dev/null @@ -1,114 +0,0 @@ -var util = require('./util'); - -/** - * 查询已经开通数据万象功能的存储桶 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.PageNumber 第几页,非必须 - * @param {String} params.PageSize 每页个数,非必须 - * @param {String} params.Regions 地域信息,例如'ap-shanghai,ap-beijing',非必须 - * @param {String} params.BucketNames 存储桶名称,以“,”分隔,支持多个存储桶,精确搜索,非必须 - * @param {String} params.BucketName 存储桶名称前缀,前缀搜索,非必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function describeMediaBuckets(params, callback) { - var host = 'ci.' + params.Region + '.myqcloud.com'; - var url = 'https://' + host + '/mediabucket'; - var query = { - pageNumber: params.PageNumber, - pageSize: params.PageSize, - regions: params.Regions, - bucketNames: params.BucketNames, - bucketName: params.BucketName, - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: 'mediabucket', - Url: url, - Query: query - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件信息 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getMediaInfo(params, callback) { - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: { - 'ci-process': 'videoinfo' - } - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -/** - * 获取媒体文件某个时间的截图 - * @param {Object} params 参数对象,必须 - * @param {String} params.Bucket Bucket名称,必须,格式:test-1250000000 - * @param {String} params.Region 地域名称,必须 - * @param {String} params.Key 文件名称,必须 - * @param {Number} params.Time 截图的时间点,单位为秒,必须 - * @param {Number} params.Width 截图的宽,非必须 - * @param {Number} params.Height 截图的高,非必须 - * @param {String} params.Format 截图的格式,支持 jpg 和 png,默认 jpg,非必须 - * @param {String} params.Rotate 图片旋转方式,非必须 - * @param {String} params.Mode 截帧方式,非必须 - * @param {Function} callback 回调函数,必须 - * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730 - * @return {Object} data 为对应的 object 数据 - */ - function getSnapshot(params, callback) { - var query = { - 'ci-process': 'snapshot', - time: params.Time || 1, - width: params.Width || 0, - height: params.Height || 0, - format: params.Format || 'jpg', - rotate: params.Rotate || 'auto', - mode: params.Mode || 'exactframe', - }; - this.request({ - Bucket: params.Bucket, - Region: params.Region, - Method: 'GET', - Key: params.Key, - Query: query, - RawBody: true, - }, function (err, data) { - if (err) return callback(err); - callback(null, data); - }); -} - -var API_MAP = { - describeMediaBuckets: describeMediaBuckets, - getMediaInfo: getMediaInfo, - getSnapshot: getSnapshot, -}; - -module.exports.init = function (COS) { - util.each(API_MAP, function (fn, apiName) { - COS.prototype[apiName] = util.apiWrapper(apiName, fn); - }); -}; \ No newline at end of file diff --git a/src/cos.js b/src/cos.js index 1ea0faf..adc6a3f 100644 --- a/src/cos.js +++ b/src/cos.js @@ -5,7 +5,6 @@ var event = require('./event'); var task = require('./task'); var base = require('./base'); var advance = require('./advance'); -var ci = require('./ci'); var defaultOptions = { SecretId: '', @@ -56,7 +55,6 @@ var COS = function (options) { base.init(COS, task); advance.init(COS, task); -ci.init(COS); COS.getAuthorization = util.getAuth; COS.version = '1.1.0'; From c10c7debf9146a2719fec902b9b5637df0357fcc Mon Sep 17 00:00:00 2001 From: chrisftian Date: Tue, 16 Nov 2021 16:10:10 +0800 Subject: [PATCH 09/10] upd demo --- demo/demo-sdk.js | 37 +++++++++++++++++++------------------ demo/test.js | 3 ++- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/demo/demo-sdk.js b/demo/demo-sdk.js index 58401ab..4155157 100644 --- a/demo/demo-sdk.js +++ b/demo/demo-sdk.js @@ -706,24 +706,24 @@ var objectDao = { logger.log('putObject:', err || data); }) }); - } - // abortUploadTask: function() { - // cos.abortUploadTask({ - // Bucket: config.Bucket, - // /* 必须 */ // Bucket 格式:test-1250000000 - // Region: config.Region, - // /* 必须 */ - // // 格式1,删除单个上传任务 - // // Level: 'task', - // // Key: '10mb.zip', - // // UploadId: '14985543913e4e2642e31db217b9a1a3d9b3cd6cf62abfda23372c8d36ffa38585492681e3', - // // 格式2,删除单个文件所有未完成上传任务 - // Level: 'file', - // Key: '10mb.zip', - // // 格式3,删除 Bucket 下所有未完成上传任务 - // // Level: 'bucket', - // }, requestCallback); - // }, + }, + 'abortUploadTask 抛弃分块上传任务': function() { + cos.abortUploadTask({ + Bucket: config.Bucket, + /* 必须 */ // Bucket 格式:test-1250000000 + Region: config.Region, + /* 必须 */ + // 格式1,删除单个上传任务 + // Level: 'task', + // Key: '10mb.zip', + // UploadId: '14985543913e4e2642e31db217b9a1a3d9b3cd6cf62abfda23372c8d36ffa38585492681e3', + // 格式2,删除单个文件所有未完成上传任务 + Level: 'file', + Key: '10mb.zip', + // 格式3,删除 Bucket 下所有未完成上传任务 + // Level: 'bucket', + }, requestCallback); + }, } var advanceObjectDao = { @@ -929,6 +929,7 @@ var ciObjectDao = { cos.request({ Bucket: config.Bucket, Region: config.Region, + Method: 'GET', Key: 'test.mp4', Query: { 'ci-process': 'snapshot', /** 固定值,必须 */ diff --git a/demo/test.js b/demo/test.js index dc7a470..a2f4721 100644 --- a/demo/test.js +++ b/demo/test.js @@ -2911,10 +2911,11 @@ group('数据万象', function () { done(); }); }); - test('describeMediaBuckets()', function (done, assert) { + test('getSnapshot()', function (done, assert) { cos.request({ Bucket: config.Bucket, Region: config.Region, + Method: 'GET', Key: 'test.mp4', Query: { 'ci-process': 'snapshot', /** 固定值,必须 */ From 52da2871c5abaa288fc9f00fe9d19e0c55aaaa81 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Tue, 16 Nov 2021 20:05:47 +0800 Subject: [PATCH 10/10] =?UTF-8?q?upd=EF=BC=9Aobj2str=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo-album/lib/cos-wx-sdk-v5.js | 74 ++++++++++++++------------------- demo/lib/cos-wx-sdk-v5.js | 74 ++++++++++++++------------------- lib/request.js | 74 ++++++++++++++------------------- 3 files changed, 93 insertions(+), 129 deletions(-) diff --git a/demo-album/lib/cos-wx-sdk-v5.js b/demo-album/lib/cos-wx-sdk-v5.js index 89302e7..410667b 100644 --- a/demo-album/lib/cos-wx-sdk-v5.js +++ b/demo-album/lib/cos-wx-sdk-v5.js @@ -8904,53 +8904,41 @@ module.exports.init = function (COS, task) { /* 18 */ /***/ (function(module, exports) { -var obj2str = function (obj) { - var i, key, val; - var list = []; - var keyList = Object.keys(obj); - for (i = 0; i < keyList.length; i++) { - key = keyList[i]; - val = obj[key] || ''; - list.push(key + '=' + encodeURIComponent(val)); - } - return list.join('&'); -}; +function camSafeUrlEncode(str) { + return encodeURIComponent(str) + .replace(/!/g, '%21') + .replace(/'/g, '%27') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + .replace(/\*/g, '%2A'); +} -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - case 'boolean': - return v ? 'true' : 'false'; - case 'number': - return isFinite(v) ? v : ''; - default: - return ''; +function getObjectKeys(obj, forKey) { + var list = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key); + } } + return list.sort(function (a, b) { + a = a.toLowerCase(); + b = b.toLowerCase(); + return a === b ? 0 : (a > b ? 1 : -1); + }); }; -var queryStringify = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - if (typeof obj === 'object') { - return Object.keys(obj).map(function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (Array.isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).filter(Boolean).join(sep); - +var obj2str = function (obj) { + var i, key, val; + var list = []; + var keyList = getObjectKeys(obj); + for (i = 0; i < keyList.length; i++) { + key = keyList[i]; + val = (obj[key] === undefined || obj[key] === null) ? '' : ('' + obj[key]); + key = camSafeUrlEncode(key).toLowerCase(); + val = camSafeUrlEncode(val) || ''; + list.push(key + '=' + val) } - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); + return list.join('&'); }; var request = function (params, callback) { @@ -9028,7 +9016,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && queryStringify(params.qs) || ''; + var qsStr = params.qs && obj2str(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; } diff --git a/demo/lib/cos-wx-sdk-v5.js b/demo/lib/cos-wx-sdk-v5.js index 89302e7..410667b 100644 --- a/demo/lib/cos-wx-sdk-v5.js +++ b/demo/lib/cos-wx-sdk-v5.js @@ -8904,53 +8904,41 @@ module.exports.init = function (COS, task) { /* 18 */ /***/ (function(module, exports) { -var obj2str = function (obj) { - var i, key, val; - var list = []; - var keyList = Object.keys(obj); - for (i = 0; i < keyList.length; i++) { - key = keyList[i]; - val = obj[key] || ''; - list.push(key + '=' + encodeURIComponent(val)); - } - return list.join('&'); -}; +function camSafeUrlEncode(str) { + return encodeURIComponent(str) + .replace(/!/g, '%21') + .replace(/'/g, '%27') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + .replace(/\*/g, '%2A'); +} -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - case 'boolean': - return v ? 'true' : 'false'; - case 'number': - return isFinite(v) ? v : ''; - default: - return ''; +function getObjectKeys(obj, forKey) { + var list = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key); + } } + return list.sort(function (a, b) { + a = a.toLowerCase(); + b = b.toLowerCase(); + return a === b ? 0 : (a > b ? 1 : -1); + }); }; -var queryStringify = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - if (typeof obj === 'object') { - return Object.keys(obj).map(function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (Array.isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).filter(Boolean).join(sep); - +var obj2str = function (obj) { + var i, key, val; + var list = []; + var keyList = getObjectKeys(obj); + for (i = 0; i < keyList.length; i++) { + key = keyList[i]; + val = (obj[key] === undefined || obj[key] === null) ? '' : ('' + obj[key]); + key = camSafeUrlEncode(key).toLowerCase(); + val = camSafeUrlEncode(val) || ''; + list.push(key + '=' + val) } - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); + return list.join('&'); }; var request = function (params, callback) { @@ -9028,7 +9016,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && queryStringify(params.qs) || ''; + var qsStr = params.qs && obj2str(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; } diff --git a/lib/request.js b/lib/request.js index 378ca9a..60b2d9f 100644 --- a/lib/request.js +++ b/lib/request.js @@ -1,50 +1,38 @@ -var obj2str = function (obj) { - var i, key, val; - var list = []; - var keyList = Object.keys(obj); - for (i = 0; i < keyList.length; i++) { - key = keyList[i]; - val = obj[key] || ''; - list.push(key + '=' + encodeURIComponent(val)); - } - return list.join('&'); -}; +function camSafeUrlEncode(str) { + return encodeURIComponent(str) + .replace(/!/g, '%21') + .replace(/'/g, '%27') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + .replace(/\*/g, '%2A'); +} -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - case 'boolean': - return v ? 'true' : 'false'; - case 'number': - return isFinite(v) ? v : ''; - default: - return ''; +function getObjectKeys(obj, forKey) { + var list = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key); + } } + return list.sort(function (a, b) { + a = a.toLowerCase(); + b = b.toLowerCase(); + return a === b ? 0 : (a > b ? 1 : -1); + }); }; -var queryStringify = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - if (typeof obj === 'object') { - return Object.keys(obj).map(function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (Array.isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).filter(Boolean).join(sep); - +var obj2str = function (obj) { + var i, key, val; + var list = []; + var keyList = getObjectKeys(obj); + for (i = 0; i < keyList.length; i++) { + key = keyList[i]; + val = (obj[key] === undefined || obj[key] === null) ? '' : ('' + obj[key]); + key = camSafeUrlEncode(key).toLowerCase(); + val = camSafeUrlEncode(val) || ''; + list.push(key + '=' + val) } - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); + return list.join('&'); }; var request = function (params, callback) { @@ -122,7 +110,7 @@ var request = function (params, callback) { }); }); } else { - var qsStr = params.qs && queryStringify(params.qs) || ''; + var qsStr = params.qs && obj2str(params.qs) || ''; if (qsStr) { url += (url.indexOf('?') > -1 ? '&' : '?') + qsStr; }