UNPKG

oss-uploader.js

Version:
426 lines (382 loc) 15.1 kB
# oss-uploader.js oss-uploader.js 是一个文件上传插件,Fork [simple-uploader.js](https://github.com/simple-uploader/Uploader),在simple-uploader.js的基础上,新增了文件上传至OSS的功能(目前仅支持七牛云和阿里云)。 git:https://github.com/LLLLLLiulei/oss-uploader.js.git ## 安装 ```console npm install oss-uploader.js ``` ## 使用 ###### 请参考[simple-uploader.js](https://github.com/simple-uploader/Uploader/blob/develop/README_zh-CN.md) ## API ###### 请参考[simple-uploader.js](https://github.com/simple-uploader/Uploader/blob/develop/README_zh-CN.md) ###### 在simple-uploader.js的基础上新增的配置如下: #### Uploader ##### 支持的配置项: * `oss` oss名称`(七牛云:qiniu,阿里云:aliyun)`,用于区分上传至哪个OSS,默认 null(使用默认上传方式) * `ossParams` oss上传时的参数配置,可以是一个对象或者一个方法(会传入当前file对象,需返回对象包含配置参数) - [x] 七牛云(qiniu) ```JavaScript let opts={ oss:'qiniu', ossParams:async function(file){ let {name} = file let res = await axios.get(`http://localhost:3000/qiniuuptoken?fileName=${name}`) let {key,token,config,putExtra} = res.data return { key, token, config, putExtra } } } //或者: opts={ oss:'qiniu', ossParams: { key:'testFile', token:'DzyD0TQsBnSYEg3ncPROPP00XoFDUNsdaadTRDGV:ZhyEPw4mjCdX7PNCpaGNNRcQpGY=:eyJzY29wZSI6InNsaW1kb2MtdGVzdDpqaWFtaTIuemlwIiwiZGVhZGxpbmUiOjE1NTUxNDA4ODl9', config:{ useCdnDomain: true, region: qiniu.region.z2 }, putExtra:{ fname: "testFile.txt", params: {}, mimeType: [] || null } } } const uploader = new Uploader(opts) ``` 参数说明(摘自七牛云(https://developer.qiniu.com/kodo/sdk/1283/javascript)): * **key(必需)**: 文件资源名 * **token(必需)**: 上传验证信息,前端通过接口请求后端获得 * **config**: `object` ```JavaScript var config = { useCdnDomain: true, region: qiniu.region.z2 }; ``` * config.useCdnDomain: 表示是否使用 cdn 加速域名,为布尔值,`true` 表示使用,默认为 `false`。 * config.disableStatisticsReport: 是否禁用日志报告,为布尔值,默认为 `false`。 * config.uphost: 上传 `host`,类型为 `string`, 如果设定该参数则优先使用该参数作为上传地址,默认为 `null`。 * config.region: 选择上传域名区域;当为 `null` 或 `undefined` 时,自动分析上传域名区域。 * config.retryCount: 上传自动重试次数(整体重试次数,而不是某个分片的重试次数);默认 3 次(即上传失败后最多重试两次);**目前仅在上传过程中产生 `599` 内部错误时生效**,**但是未来很可能会扩展为支持更多的情况**。 * config.concurrentRequestLimit: 分片上传的并发请求量,`number`,默认为3;因为浏览器本身也会限制最大并发量,所以最大并发量与浏览器有关。 * config.checkByMD5: 是否开启 MD5 校验,为布尔值;在断点续传时,开启 MD5 校验会将已上传的分片与当前分片进行 MD5 值比对,若不一致,则重传该分片,避免使用错误的分片。读取分片内容并计算 MD5 需要花费一定的时间,因此会稍微增加断点续传时的耗时,默认为 false,不开启。 * config.forceDirect: 是否上传全部采用直传方式,为布尔值;为 `true` 时则上传方式全部为直传 form 方式,禁用断点续传,默认 `false`。 * **putExtra**: ```JavaScript var putExtra = { fname: "", params: {}, mimeType: [] || null }; ``` * fname: `string`,文件原文件名 * params: `object`,用来放置自定义变量 * mimeType: `null || array`,用来限制上传文件类型,为 `null` 时表示不对文件类型限制;限制类型放到数组里: `["image/png", "image/jpeg", "image/gif"]` - [x] 阿里云(aliyun) ```JavaScript let opts={ oss:'aliyun', ossParams:async function(file){ let {name} = file let options = {} let res = await axios.get(`http://localhost:3000/aliuptoken?fileName=${name}`) let ossConfig = res.data.data return { ossConfig, name options } } } //或者: opts={ oss:'aliyun', ossParams: { ossConfig :{ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: '<Your bucket name>', }, name:'testFile', options:{} } } const uploader = new Uploader(opts) ``` 参数说明(摘自阿里云(https://help.aliyun.com/document_detail/64047.html?spm=a2c4g.11174283.6.1048.1a3a7da2LulhtJ#h2-url-2)): - ossConfig \{Object\} oss配置项 - \[accessKeyId\] \{String\}:通过阿里云控制台创建的access key。 - \[accessKeySecret\] \{String\}:通过阿里云控制台创建的access secret。 - \[stsToken\] \{String\}:使用临时授权方式,详情请参见[使用STS访问](cn.zh-CN/SDK 参考/Node.js/授权访问.md#)。 - \[bucket\] \{String\}:通过控制台创建的bucket。 - \[endpoint\] \{String\}:OSS域名。 - \[region\] \{String\}:bucket 所在的区域,默认 oss-cn-hangzhou。 - \[internal\] \{Boolean\}:是否使用阿里云内网访问,默认false。比如通过ECS访问OSS,则设置为true,采用internal的endpoint可节约费用。 - \[cname\] \{Boolean\}:是否支持上传自定义域名,默认false。如果cname为true,endpoint传入自定义域名时,自定义域名需要先同bucket进行绑定。 - \[isRequestPay\] \{Boolean\}:bucket是否开启请求者付费模式,默认false。具体可查看[请求者付费模式](../../../../../cn.zh-CN/开发指南/存储空间(Bucket)/请求者付费模式.md#)。 - \[secure\] \{Boolean\}: \(secure: true\) 则使用 HTTPS, \(secure: false\) 则使用 HTTP,详情请查看[常见问题](cn.zh-CN/SDK 参考/Node.js/常见问题.md#)。 - \[timeout\] \{String|Number\}:超时时间,默认 60s。 - name \{String\} Object名称。 - \[options\] \{Object\} 额外参数 。 - \[checkpoint\] \{Object\} 断点记录点。如果设置这个参数,上传会从断点开始;如果没有设置,则重新上传。 - file \{File\} 用户选取的文件对象,浏览器重启后需要用户手动触发进行设置。 - name \{String\} 上传的object key。 - fileSize \{Number\} 文件大小。 - partSize \{Number\} 分片大小。 - uploadId \{String\} 分片上传的ID。 - doneParts \{Array\} 已完成分片的数组,包含的对象结构如下: - number \{Number\} 分片的number。 - etag \{String\} 分片的etag。 - \[parallel\] \{Number\} 并发上传的分片个数。 - \[partSize\] \{Number\} 分片大小。 - \[progress\] \{Function\} `function`、 `async` 、`promise` 形式,回调函数包含三个参数: - percentage \{Number\} 进度百分比\(0-1之间小数\)。 - checkpoint \{Object\} 断点记录点。 - res \{Object\}\) 单次part成功返回的response。 - \[meta\] \{Object\} 用户自定义header meta信息,header前缀 `x-oss-meta-`。 - \[mime\] \{String\} 用户自定义`Content-Type header` 。 - \[headers\] \{Object\} http额外的头字段,详情请看 [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616.html) 。 - 'Cache-Control' 通用消息头被用在http请求和响应中,通过指定指令来实现缓存机制, 例如`Cache-Control: public, no-cache`。 - 'Content-Disposition' 指定回复的内容该以何种形式展示。是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地,例如`Content-Disposition: somename`。 - 'Content-Encoding' 用于对特定媒体类型的数据进行压缩, 例如`Content-Encoding: gzip`。 - 'Expires' 过期时间,例如`Expires: 3600000`。 - \[callback\] \{Object\} callback回调设置。 - url \{String\} 和oss server交互的回调服务器地址,对应CallBack参数中的callbackUrl。 - body \{String\} 发起回调时请求body的值,对应CallBack参数中的callbackBody。body值为JSON格式。 - \[host\] \{String\} 发起回调请求时Host头的值,对应CallBack参数中的callbackHost。 - \[contentType\] \{String\} 发起回调请求的Content-Type,对应CallBack参数中的callbackBodyType。 - \[customValue\] \{Object\} 发起回调请求自定义参数,对应CallBack参数中的callback-var。 示列: app.vue ``` <template> <div> <uploader :options="options" :file-status-text="statusText" class="uploader-example" ref="uploader" @file-complete="fileComplete" @complete="complete" ></uploader> </div> </template> <script> const axios = require('axios') const getQinniuOssparams = async function (file) { let token = await axios.get('http://localhost:3000/qiniuuptoken?fileName=' + file.name) token = token.data console.log('token', token) return { token, key: file.name } } const getAliOssparams = async function (file) { let data = await axios.get('http://localhost:3000/aliuptoken?fileName=' + file.name) let ossParams = { ossConfig: data.data, name: file.name } return ossParams } export default { data () { return { options: { target: '//localhost:3000/upload', // '//jsonplaceholder.typicode.com/posts/', testChunks: false, oss: 'aliyun', ossParams: getAliOssparams }, attrs: { accept: 'image/*' }, statusText: { success: '成功了', error: '出错了', uploading: '上传中', paused: '暂停中', waiting: '等待中' } } }, methods: { complete () { console.log('complete', arguments) }, fileComplete () { console.log('file complete', arguments) } }, mounted () { this.$nextTick(() => { window.uploader = this.$refs.uploader.uploader }) } } </script> ``` uploader.vue ``` <template> <div class="uploader"> <slot :files="files" :file-list="fileList" :started="started"> <uploader-unsupport></uploader-unsupport> <uploader-drop> <p>Drop files here to upload or</p> <uploader-btn>select files</uploader-btn> <uploader-btn :directory="true">select folder</uploader-btn> </uploader-drop> <uploader-list></uploader-list> </slot> </div> </template> <script> // import Uploader from 'simple-uploader.js' // import Uploader from '../uploader/uploader.js' import Uploader from 'oss-uploader.js' import { kebabCase } from '../common/utils' import UploaderBtn from './btn.vue' import UploaderDrop from './drop.vue' import UploaderUnsupport from './unsupport.vue' import UploaderList from './list.vue' import UploaderFiles from './files.vue' import UploaderFile from './file.vue' const COMPONENT_NAME = 'uploader' const FILE_ADDED_EVENT = 'fileAdded' const FILES_ADDED_EVENT = 'filesAdded' const UPLOAD_START_EVENT = 'uploadStart' export default { name: COMPONENT_NAME, provide () { return { uploader: this } }, props: { options: { type: Object, default () { return {} } }, autoStart: { type: Boolean, default: true }, fileStatusText: { type: [Object, Function], default () { return { success: 'success', error: 'error', uploading: 'uploading', paused: 'paused', waiting: 'waiting' } } } }, data () { return { started: false, files: [], fileList: [] } }, methods: { uploadStart () { this.started = true }, fileAdded (file) { this.$emit(kebabCase(FILE_ADDED_EVENT), file) if (file.ignored) { // is ignored, filter it return false } }, filesAdded (files, fileList) { this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList) if (files.ignored || fileList.ignored) { // is ignored, filter it return false } }, fileRemoved (file) { this.files = this.uploader.files this.fileList = this.uploader.fileList }, filesSubmitted (files, fileList) { this.files = this.uploader.files this.fileList = this.uploader.fileList if (this.autoStart) { this.uploader.upload() } }, allEvent (...args) { const name = args[0] const EVENTSMAP = { [FILE_ADDED_EVENT]: true, [FILES_ADDED_EVENT]: true, [UPLOAD_START_EVENT]: 'uploadStart' } const handler = EVENTSMAP[name] if (handler) { if (handler === true) { return } this[handler].apply(this, args.slice(1)) } args[0] = kebabCase(name) this.$emit.apply(this, args) } }, created () { console.log(console) this.options.initialPaused = !this.autoStart const uploader = new Uploader(this.options) this.uploader = uploader console.log(uploader) this.uploader.fileStatusText = this.fileStatusText uploader.on('catchAll', this.allEvent) uploader.on(FILE_ADDED_EVENT, this.fileAdded) uploader.on(FILES_ADDED_EVENT, this.filesAdded) uploader.on('fileRemoved', this.fileRemoved) uploader.on('filesSubmitted', this.filesSubmitted) }, destroyed () { const uploader = this.uploader uploader.off('catchAll', this.allEvent) uploader.off(FILE_ADDED_EVENT, this.fileAdded) uploader.off(FILES_ADDED_EVENT, this.filesAdded) uploader.off('fileRemoved', this.fileRemoved) uploader.off('filesSubmitted', this.filesSubmitted) this.uploader = null }, components: { UploaderBtn, UploaderDrop, UploaderUnsupport, UploaderList, UploaderFiles, UploaderFile } } </script> <style> .uploader { position: relative; } </style> ``` ## 源 oss-uploader.js 是 FORK 的 https://github.com/simple-uploader/Uploader ,参考了 https://github.com/qiniu/js-sdk , https://github.com/ali-sdk/ali-oss