8383</template >
8484
8585<script >
86- import AliOSS from ' ali-oss'
8786import ImgPreview from ' @femessage/img-preview'
88- import ImageCompressor from ' image-compressor.js '
87+ import Compressor from ' compressorjs '
8988import DraggableList from ' ./components/draggable-list.vue'
9089import UploadItem from ' ./components/upload-item.vue'
91- import {encodePath } from ' ./utils'
92-
93- const imageCompressor = new ImageCompressor ()
90+ import {getSignature } from ' ./utils'
9491
9592const oneKB = 1024
9693
@@ -108,20 +105,11 @@ export default {
108105 },
109106 props: {
110107 /**
111- * 阿里云控制台创建的access key
112- * 使用前请务必设置跨域 及 ACL
113- * @link https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.920.9ddd5557vJ6QU7
114- */
115- accessKeyId: {
116- type: String ,
117- default: process .env .OSS_KEY
118- },
119- /**
120- * 阿里云控制台创建的access secret
108+ * 上传地址
121109 */
122- accessKeySecret : {
110+ action : {
123111 type: String ,
124- default: process .env .OSS_SECRET
112+ default: process .env .UPLOAD_ACTION
125113 },
126114 /**
127115 * 存储空间的名字
@@ -207,7 +195,7 @@ export default {
207195 validator : val => val > 0
208196 },
209197 /**
210- * 图片压缩参数,请参考:https://www.npmjs.com/package/image-compressor.js #options
198+ * 图片压缩参数,请参考:https://www.npmjs.com/package/compressorjs #options
211199 */
212200 compressOptions: {
213201 type: Object ,
@@ -225,7 +213,7 @@ export default {
225213 })
226214 },
227215 /**
228- * 是否开启预览功能,需要全局注册img-preview组件
216+ * 是否开启预览功能,需要全局注册 img-preview 组件
229217 */
230218 preview: {
231219 type: Boolean ,
@@ -274,50 +262,40 @@ export default {
274262 },
275263
276264 /**
277- * 自定义上传, 使用此函数则不采用默认 AliOSS 上传行为
265+ * 自定义上传, 使用此函数则会覆盖默认的上传行为
278266 * 返回 Promise, 接收 resolve 参数为 url
279267 */
280- httpRequest : {
268+ request : {
281269 type: Function ,
282- async default (file ) {
283- const {name } = file
284- // 文件名-时间戳 作为上传文件key
285- const pos = name .lastIndexOf (' .' )
286- const key =
287- pos === - 1
288- ? ` ${ name} -${ Date .now ()} `
289- : ` ${ name .slice (0 , pos)} -${ Date .now ()}${ name .slice (pos)} `
290- const client = this .newClient ()
291- try {
292- const res = await client .multipartUpload (
293- this .dir + key,
294- file,
295- this .uploadOptions
296- )
297- // 协议无关
298- let url
299- // 上传时阿里 OSS 会对文件名 encode,但 res.name 没有 encode
300- // 因此要 encode res.name,否则会因为文件名不同,导致 404
301- const filename = encodePath (res .name )
302- if (this .customDomain ) {
303- if (this .customDomain .indexOf (' //' ) > - 1 )
304- url = ` ${ this .customDomain } /${ filename} `
305- else {
306- url = ` //${ this .customDomain } /${ filename} `
270+ default (file ) {
271+ const formData = new FormData ()
272+ ;[' bucket' , ' region' , ' customDomain' , ' dir' ]
273+ .filter (key => this [key])
274+ .forEach (key => formData .append (key, this [key]))
275+ formData .append (' file' , file)
276+
277+ return new Promise ((resolve , reject ) => {
278+ const xhr = new XMLHttpRequest ()
279+ xhr .responseType = ' json'
280+ xhr .onload = () => {
281+ if (xhr .status === 200 ) {
282+ resolve (xhr .response .payload .url )
283+ } else {
284+ reject (xhr .response )
307285 }
308- } else {
309- url = ` //${ this .bucket } .${ this .region } .aliyuncs.com/${ filename} `
310- }
311- return url
312- } catch (error) {
313- if (client .isCancel ()) {
314- /**
315- * 上传操作被取消事件
316- */
317- this .$emit (' cancel' )
318286 }
319- throw error
320- }
287+ xhr .onerror = reject
288+ const timestamp = Date .now ()
289+ const sep = this .action .indexOf (' ?' ) > - 1 ? ' &' : ' ?'
290+ const url = ` ${ this .action }${ sep} _=${ timestamp} `
291+ xhr .open (' POST' , url, true )
292+
293+ const signature = getSignature (location .origin , timestamp)
294+ xhr .setRequestHeader (' x-upload-timestamp' , timestamp)
295+ xhr .setRequestHeader (' x-upload-signature' , signature)
296+
297+ xhr .send (formData)
298+ })
321299 }
322300 }
323301 },
@@ -351,25 +329,6 @@ export default {
351329 }
352330 },
353331 methods: {
354- newClient () {
355- const missingKey = [
356- ' region' ,
357- ' bucket' ,
358- ' accessKeyId' ,
359- ' accessKeySecret'
360- ].find (k => ! this [k])
361- if (missingKey) {
362- throw new Error (` 必要参数不能为空: ${ missingKey} ` )
363- }
364-
365- // https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.801.LllSVA
366- return new AliOSS ({
367- region: this .region ,
368- bucket: this .bucket ,
369- accessKeyId: this .accessKeyId ,
370- accessKeySecret: this .accessKeySecret
371- })
372- },
373332 onDelete (url , index ) {
374333 const result = this .multiple ? this .uploadList .filter (v => v !== url) : ' '
375334 this .$emit (' input' , result)
@@ -447,18 +406,26 @@ export default {
447406 const max = this .multiple ? this .max : 1
448407 for (let i = 0 ; i < files .length && this .uploadList .length < max; i++ ) {
449408 // 尝试压缩文件
450- const file = enableCompressRegex .test (files[i].type )
451- ? await imageCompressor .compress (files[i], this .compressOptions )
452- : files[i]
453-
409+ let file = files[i]
410+ if (enableCompressRegex .test (file .type )) {
411+ const blob = await new Promise ((resolve , reject ) => {
412+ new Compressor (file, {
413+ ... this .compressOptions ,
414+ success: resolve,
415+ error: reject
416+ })
417+ })
418+ /* eslint-disable-next-line require-atomic-updates */
419+ file = new File ([blob], file .name )
420+ }
454421 /**
455422 * 上传过程中
456423 * @property {string} name - 当前上传的图片名称
457424 */
458425 this .$emit (' loading' , file .name )
459426
460427 try {
461- const url = await this .httpRequest (file)
428+ const url = await this .request (file)
462429 if (typeof url !== ' string' || ! / ^ (https? :)? \/\/ / .test (url)) {
463430 throw new Error (
464431 ` \` Promise.resolve\` 接收的参数应该是超链接(url), 当前为 ${ typeof url} .`
@@ -468,17 +435,10 @@ export default {
468435 currentUploads .push (url)
469436 } catch (error) {
470437 console .warn (error .message )
471- if (error .code === ' ConnectionTimeoutError' ) {
472- /**
473- * 上传超时
474- */
475- this .$emit (' timeout' )
476- } else {
477- /**
478- * 上传失败
479- */
480- this .$emit (' fail' )
481- }
438+ /**
439+ * 上传失败
440+ */
441+ this .$emit (' fail' )
482442 }
483443 }
484444
0 commit comments