Giter Club home page Giter Club logo

node-sdk's Introduction

UPYUN JS SDK

NPM version Build Status dependencies Status

upyun js sdk, 支持服务端和客户端使用,集成:

  • 安全起见,浏览器端不能设置操作员账号名和密码
  • 服务端需要设置操作员账号名和密码
  • 浏览器端使用时,部分参数设置或方法调用会导致跨域失败问题
    • listDir 设置 limit | order | iter
    • putFile 设置 Content-Type 以外的其他选项
    • makeDir | updateMetadata | blockUpload | copy 无法在浏览器端使用
    • deleteFile 无法再浏览器端使用异步删除

安装

npm

$ npm install upyun --production --save

cdn

浏览器端手动安装时,需要手动引入 sdk 的依赖 axios (考虑到方便 axios 被复用,浏览器版本构建时,没有引入此依赖)

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

再引入编译后的 sdk 文件

<script src="https://unpkg.com/upyun/dist/upyun.min.js"></script>

测试

$ npm run test

接口列表

所有的接口返回均是 Promise

Client

初始化

const client = new upyun.Client(service[, options][, getHeaderSignCallback])

参数

  • service: 又拍云服务,Service 实例: new upyun.Service('your service name', 'your operator name', 'your operator password')
  • options: 配置项,可以配置以下参数
    • domain: 又拍云 rest api 地址,默认 v0.api.upyun.com 其他可配置域名见又拍云文档
    • protocol: 使用 http|https 协议,默认 https 协议
    • proxy: 代理配置见使用说明. 默认为 undefined.
  • getHeaderSignCallback: 获取又拍云 HTTP Header 签名回调函数,服务端使用时不需要设置该参数。客户端使用必须设置该回调函数,它接受四个参数:service, method, path, contentMD5, 用于计算当前请求签名,其中 contentMD5 可选填。如果回调函数是异步,则必须返回一个 Promise

示例

  • 服务端使用,一般只需要配置完整又拍云服务信息(服务名、操作员名、操作员密码)即可:
const service = new upyun.Service('your service name', 'your operator name', 'your operator password')
const client = new upyun.Client(service);
  • 客户端使用,必须设置签名回调函数,又拍云服务信息只需服务名即可(注意:如果回调函数是异步,则必须返回一个 Promise
/**
 * @param {!Service} service: Service 实例
 * @param {!string} method: 当前请求的 API 使用的方法
 * @param {!string} path: 当前请求的资源路径
 * @param {?string} contentMD5 内容的 md5 值
 */
function getSignHeader(service, method, path, contentMD5 = null) {
  // 请求自己的服务器,计算当前 api 请求签名信息
  // 可以参考该项目 sample 目录中的示例代码
  ...
}
const service = new upyun.Service('your service name')
const client = new upyun.Client(service, getSignHeader);

usage(path = '/')

查看目录大小(单位: byte)

参数

  • path: 目录路径

示例

client.usage('/sub/dir').then(function(size) {
  console.log('/sub/dir total used size: ' + size)
})

listDir(remotePath, options)

获取目录下文件列表

参数

  • remotePath: 需要查看的目录路径
  • options:
    • limit: 每次请求获取的目录最大列表,最大值 10000,默认 100
    • order: 列表以文件最后修改时间排序,可选值 asc|desc,默认 asc
    • iter: 遍历起点,每次响应参数中,将会包含遍历下一页需要的 iter

响应

目录不存在,返回 false,否则返回一个对象,结构如下:

{
  files: [
    {
      name: 'example.txt', // file or dir name
      type: 'N', // file type, N: file; F: dir
      size: 28392812, // file size
      time: 1486053098 // last modify time
    }
  ],
  next: 'dlam9pd2Vmd2Z3Zg==' // next page iter
}

putFile(remotePath, localFile, options = {})

通过 rest api 上传文件

参数

  • remotePath: 文件保存路径 需包含文件名路径不需要 encodeURI,sdk 会统一处理
  • localFile: 需要上传的文件。服务端支持 String | Stream | Buffer, 浏览器端支持 File | String 注意 String 表示文件内容,不是本地文件路径
  • options: 其他可选参数 Content-MD5 | Content-Length | Content-Type | Content-Secret | x-gmkerl-thumb | x-upyun-meta-x | x-upyun-meta-ttl(大小写无关,详见上传参数),其中 Content-Type 未设置时,将会根据文件路径设置默认值

响应

如果是非图片类文件,上传成功返回 true, 否则返回一个对象,包含图片的基本信息:

{
  width: 80,
  height: 80,
  'file-type': 'image/jpg',
  frames: 1
}

如果上传失败,返回 false

initMultipartUpload(remotePath, fileOrPath, options = {})

初始化一个并行式断点续传任务

参数

  • remotePath: 文件保存路径 需包含文件名路径不需要 encodeURI,sdk 会统一处理
  • fileOrPath: 需要上传的文件。服务端支持 Buffer 和文件路径 String, 浏览器端支持 File
  • options: 其他可选参数 Content-MD5 | X-Upyun-Multi-Type | X-Upyun-Meta-X | X-Upyun-Meta-Ttl(大小写无关,详见上传参数),其中 Content-Type 未设置时,将会根据文件路径设置默认值。

响应

初始化成功,返回一个对象:

{
  fileSize: 55997,
  partCount: 1,
  uuid: 'b2326f91-c5c4-4c6e-bce9-a41dae78ca2a'
}

如果初始化失败,返回 false

multipartUpload (remotePath, fileOrPath, multiUuid, partId)

参数

  • remotePath: 文件保存路径 需包含文件名路径不需要 encodeURI,sdk 会统一处理
  • fileOrPath: 需要上传的文件。服务端支持 Buffer 和文件路径 String, 浏览器端支持 File
  • multiUuid: 任务标识,初始化时生成。即 X-Upyun-Multi-Uuid
  • partId 分块序号,序号从 0 开始. 即 X-Upyun-Part-Id

响应

数据传输成功返回 true, 反之返回 false

completeMultipartUpload (remotePath, multiUuid)

参数

  • remotePath: 文件保存路径 需包含文件名路径不需要 encodeURI,sdk 会统一处理
  • multiUuid: 任务标识,初始化时生成。即 X-Upyun-Multi-Uuid

响应

数据传输成功返回 true, 反之返回 false

makeDir(remotePath)

创建目录

参数

  • remotePath: 新建目录的路径

响应

创建成功返回 true,否则 false

headFile(remotePath)

HEAD 请求,获取文件基本信息

参数

  • remotePath: 文件在又拍云云存储服务的路径

响应

文件不存在返回 false。否则返回一个对象,结构如下,详见又拍云 HEAD

{
  'type': 'file', // 文件类型
  'size': 289239, // 文件大小
  'date': 1486053098, // 文件创建时间
  'Content-Md5': '9a56c9d185758d2eda3751e03b891fce'  // 文件 md5 值
}

deleteFile(remotePath)

删除文件或目录

参数

  • remotePath: 文件或目录在又拍云服务的路径

响应

删除成功返回 true, 否则返回 false

getFile(remotePath, saveStream = null)

下载保存在又拍云服务的文件

参数

  • remotePath: 需要下载的文件路径
  • saveStream: 可选值,一个可以写入的流。若传递该参数,下载的文件将直接写入该流。该参数不支持浏览器端使用

响应

如果文件不存在,将会返回 false。文件存在时,若没有设置 saveStream,该方法 将直接返回文件内容。若设置了 saveStream,文件将直接写入该流,并返回流信息

示例

获取文件内容

client.getFile('/sample.txt').then(function (content) {
  console.log(content) // will out put file content directly
})

写入其他流

const saveTo = fs.createWriteStream('./localSample.txt')
client.getFile('/sample.txt', saveTo).then(function (stream) {
  // file has been saved to localSample.txt
  // you can pipe the stream to anywhere you want
})

formPutFile(remotePath, localFile, params = {}, opts = {})

使用又拍云表单 api 上传文件。客户端使用该方法时, 必须先设置获取又拍云 HTTP Body 签名的回调函数

参数

  • remotePath: 保存路径
  • localFile: 需要上传的文件,和 putFile 相同(**如果在浏览器端使用,只支持 String/Blob/File **)
  • params: 又拍云表单 api 支持的可选参数(service(同 bucket), save-key 两个必选参数不需要手动在这里设置)
  • opts
    • filename 可选参数. 用于指定上传字符串/ Blob 的文件名. 支持路径取 basename. 文件名取值优先级 filename > localFile 是文件 > 默认值 "file"

响应

成功返回一个对象,详细说明见异步通知规则参数说明部分,失败返回 false

copy(targetPath, sourcePath, options = {})

将文件 sourcePath 拷贝至 targetPath,不适用于文件夹。

参数

  • sourcePath: 原文件地址
  • targetPath: 目标文件地址
  • options: 其他可选参数 x-upyun-metadata-directive | content-md5 | content-length(无视大小写)

响应

操作成功返回 true, 反之返回 false

move(targetPath, sourcePath, options = {})

将文件 sourcePath 移动并重命名至 targetPath,不适用于文件夹。

参数

  • sourcePath: 原文件地址
  • targetPath: 目标文件地址
  • options: 其他可选参数 x-upyun-metadata-directive | content-md5 | content-length(无视大小写)

响应

操作成功返回 true, 反之返回 false

Service

又拍云服务,包含以下属性

  • serviceName 服务名
  • operatorName 操作员名
  • password 操作员密码,读取该属性时,获取的值是 md5 加密后的结果

sign

签名模块

备注

upyun npm package 曾为 James Chen 所有。

经过与其的交流协商,James 已经将此 npm 包转由 UPYUN 开发团队管理和维护。

后续的代码和版本更新,将于原有的项目无任何直接关系。

在 npm 上, "upyun": "<=0.0.3" 是由 James Chen 曾开发的 node-upyun 项目.

非常感谢 James Chen 对 upyun 的支持和贡献

node-sdk's People

Contributors

743v45 avatar arrebole avatar di4urp avatar forthe2008 avatar kaidiren avatar lanfei avatar lisposter avatar llawlight avatar rifewang avatar sabakugaara avatar tokune avatar yejingx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

node-sdk's Issues

nodejs端上传string显示401

const BUCKET = '服务名';
const BUCKET_URL_ROOT = '域名';
const FROM_API_SECRET = '密码';
const ADMIN_USERNAME = '账号';
const upService = new upyun.Service(BUCKET, ADMIN_USERNAME, FROM_API_SECRET);
const upClient = new upyun.Client(upService);
const params = { 'notify-url': BUCKET_URL_ROOT };
const fileName = "文件名.html";
const fileString = "一段html字符串";
upClient.putFile(fileName, fileString, params).then(res => {
console.log(res);
}).catch(err => {
console.log(err)
})

错误是upyun - response error: Request failed with status code 401

有点懵逼 , 我是在nodejs端直接调用的,fileString是字符串,因为我看你们的文档是支持直接字符串上传的,求解

遍历所有文件

你好,我们有多层目录,如何使用listDir借口,输入第一层目录,自动遍历所有文件,我们遍历时会提示too many requests

README.md 代码有误

文档中有几处类似如下的代码:

const upyun = new upyun.Client(bucket[, options][, getHeaderSignCallback])

new upyun.Client() 看,upyun 是个已存在的对象,也就是 upyun 模块本身,可以猜测上面的语句是这样的:

const upyun = require('upyun');

const upyun = new upyun.Client(bucket[, options][, getHeaderSignCallback])

相当于定义了两次 upyun 常量。

formPutFile 返回值问题

formPutFile 只返回 truefalse,对于将 save-key 设置为 /{random32}{.suffix}/ 的请求,上传成功后,根本拿不到文件名。

formPutFile 图片上传成功但是无法查看预览

let imgBuffer = new Buffer.from(imgData, 'base64')
let uploadData = await upyunClient.formPutFile(/website/${file.name}, imgBuffer, {"Content-Type": file.type});

将浏览器端上传的base64 图片转成buffer 后上传,接口调用成功。但是图片无法预览查看
image
image

sample 代码上传401呀

本地运行,没有动你们代码,上传401,
改动账号为自己的账号管理员,仍然401,望快速解决

接入很顺利,但有几个小建议

  1. policysignature 的生成能否直接封装成方法呢?
  2. return-url 不以 httphttps 开头的时候,能否通过请求的 Origin 头或 Referer 头来拼接?

场景如下:
通常我们的项目都会部署在多个环境,比如本地开发环境,测试环境,预发布环境,生产环境等等,而这些环境的域名也不一样,那么我在生成 policy 的时候,就得对应不同的环境去配置不同的 return-url ,这个虽然不难,但实在不够优雅,所以如果可以直接这样配置:

{
    'bucket': bucket,
    'save-key': filename,
    'return-url': '/api/files/callback',
    'expiration': Math.round(Date.now() / 1000) + 3600
}

就可以适用所有场景的话,就最好了。

调用put fie 但响应状态吗为401

response body:

{"msg":"need date header","code":40100001,"id":"fd9e0c412907109f04a169abaf5d7f5f"}   

控制台错误:

spread.js:25 Refused to set unsafe header "Date"
(anonymous) @ spread.js:25
v @ index.js:20
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
spread.js:25 Refused to set unsafe header "User-agent"
(anonymous) @ spread.js:25
v @ index.js:20
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25

问下怎么解决此类问题;或者是说这个方法只适合服务端调用。

amr音频转MP3无法实现

如题,代码
var options = {"type": "audio", "avopts": "/f/mp3", "return_info": true, "save_as": "/test.mp3"}
upyun.putFile(‘/test.amr’,filebuffer, 'amr', false, options, function (err, result) {
console.log(result);
});

结果:amr存储成功,转码不成功

client.putFile 会多出来一个 _o 的同名文件

client.putFile(remotePath, fs.readFileSync(file.path)).then(function(result) {

这个方法中,传入文件名之后,实际传到服务器上会有两个文件,一个是原文件名,一个是文件名_o.xxx

大概是从今年年初开始的

WX20191124-233607@2x

能否开放proxy选项

公司线上网络无法访问up云,只能给v0.api.upyun.com开通代理,但是必须在代码中使用。
即create-req.js中
const req = axios.create({
baseURL: endpoint + '/' + service.serviceName,
maxRedirects: 0,
proxy: ...
})

提示user not exists错误

var UpYun = require('./sdk');

var bucket='空间名字';
var operator='操作员';
var password ='操作员密码';

var upyun = new UpYun('bucket', 'operator', 'password ', 'v0.api.upyun.com', {
    apiVersion: 'v2'
});


upyun.usage(function(err, result) {
    console.log(result);
})

这样写的,提示4010006,user not exists'错误,麻烦看看

缓存刷新

我在这个 SDK 里没有找到缓存刷新的功能,这个 SDK 支持 缓存刷新 的功能么?如果没有的话将来会有么?

能否提供 Buffer 或 Stream 上传的 API?

有时候需要在服务端进行上传,比如微信登录接入抓取头像等,按现有 API,只能保存到本地,再进行上传,再删除保存的临时文件,这样不但麻烦,性能也差,所以请问能否提供 Buffer 或 Stream 上传的 API?

FormPutFile 上传 Base64 编码的图片失败

return upyun.formPutFile('/{year}/{mon}/{day}/images/artworks/{random32}{.suffix}', snapshotData, { b64encoded: 'on' })

返回 400,

{"code":400,"url":"","time":1504591341,"message":"need file","no-sign":"6e1174292609bfdd23e0b54eb6e646b5"}

putFile options Content-MD5 返回401

const md5 = require('md5');
fs.readFile(filepath, async (err, data) => {
  if (err) throw err;
  // 计算文件md5,并存储到upyun
  await this.client.putFile(`/test/c/index2.html`, data, {
     'Content-MD5': md5(data)
   });
});

账号密码没有问题 不加options也没有问题 一加上options就返回401

42900002 too many requests of the same uri

我这边图片上传已经使用 async eachLimit 进行了并发限制为2 为何有时候还是会报这个错误

eachLimit(imgbox, 2, (img, cb) => {
upyun.putFile(xx, xx)
.then(res => {
log(上传成功: xx)
cb()
})
.catch(err => {
reject(上传失败: xx)
cb()
})
})

报错啊大兄弟

create-req.js?f663:27 Uncaught (in promise) TypeError: Cannot read property 'then' of undefined
at webpack_exports.a.req.interceptors.request.use (create-req.js?f663:27)
image

copy接口报错

Uncaught (in promise) TypeError: utils.isSuccess is not a function at eval (upyun.esm.js?814b:2915)
查看代码发现upyun.esm.js中utils有问题,希望早日修复
upyun.esm.js中的utils如下:

var utils = {
  readBlockAsync: readBlockAsync
};

而upyun.common.js中的utils为:

var utils = {
  readBlockAsync: readBlockAsync,
  getFileSizeAsync: getFileSizeAsync,
  getContentType: getContentType,
  isSuccess: isSuccess
};

缺少了三个函数

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.