请选择 进入手机版 | 继续访问电脑版
返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

前端vue如何实现上传文件至群晖 Synology

[复制链接]
游侠 显示全部楼层 发表于 2023-10-10 10:17:23 |阅读模式 打印 上一主题 下一主题

登录网站,浏览更多精彩内容

您需要 登录 才可以下载或查看,没有账号?加入我们

x
2 u5 E- H) Y6 R: L$ B7 {

' n& x$ E* M  r. G9 q* Y1 \8 L+ G8 R前言:
; ^, h" A9 @) Y' _工作中遇到的需求千奇百怪,最近接到一个需求,需要实现上传文件时,选择上传至oss或者群晖服务器的某个文件夹中。本想着直接对接后端便可以了,哪曾想是要直接去请求群晖的接口,下面列出调研群晖上传时使用过的一些接口
; C$ ^& |9 A8 ^一、Class 定义一个构造函数" e1 }& n5 X" L& P
根据你业务需要,去配置你构造函数的入参
% H, s, e" O) }/ w7 I/ w& ^+ N! P
7 {1 K' I) U; d$ u, S" s1 v. [# o3 V8 l
  1. class QunHuiUpload { % ~" v. @; y/ v' O1 \9 G
  2.     constructor(file = {}, conf = {}, data = {}, hook = {}) {# X# p; ?1 ]) o, O$ t7 X$ G. f& d5 E: \
  3.     /**, p! O0 c9 C6 s2 D! r1 C
  4.      * 上传构造器& i7 @( t9 ]4 ~6 B: Y% D6 P
  5.      * @param {File} file 文件9 C! R1 C7 B. |0 e! U* S4 g8 \
  6.      * @param {Object} conf 字段配置
    " ~* `6 {$ a2 W. {0 a
  7.      * @param {Object} data 上传时的附加数据( R( |' Z* N7 Q) B- ]2 p% x
  8.      * @param {Object} hook 上传事件钩子
    0 E- P/ T$ }1 d" ]" r
  9.      */
    # }+ a, l  y$ S
  10.   }+ x! d% k. M8 \! r0 x3 E) {

  11. 0 M# t4 {% g, Q) {- W( v
复制代码
二、实现群晖登录
群晖上传的前提,首先是需要进行登录,登录成功后会获取到群晖sid,也就是token,用于其他接口作为参数传递。登录成功后,须将sid保存
  1. /**
    3 e, ^; N$ k7 z2 I8 D* ~
  2.    * @descitption 群晖登录- s0 W9 S* C+ G, ]. }
  3.    * @param {String} account 账户* m" t, e) O3 b8 g) f  ~6 i7 b" F
  4.    * @param {String} password 密码
    0 L: B) r0 I: O6 }3 k! i" R
  5.    */* A( Z8 B3 h8 t3 }7 a6 @' J0 q
  6. qunhuiLogin(account, password) {( c7 v) T8 S7 @( ?4 [
  7.     return new Promise((resolve, reject) => {' O& k  K6 U/ E
  8.       axios.get(`接口域名地址/webapi/auth.cgi?api=SYNO.API.Auth&version=3&method=login&account=${account}&passwd=${password}&session=FileStation&format=cookie`)- d3 \) q0 b: ^2 R
  9.         .then(res => {5 B  b/ G) k# ~; Y& [. l& a
  10.           localStorage.setItem('QunHuiToken', res.data.data.sid)
    7 x+ T: X+ ^# T; x
  11.           resolve(res.data.data.sid)
    ! o+ y' y7 X/ f9 G* W% M) ^
  12.         }).catch(err => {; ^! v/ l; v/ K& T
  13.           reject(err). k6 ]" p! T* Y4 ], P+ i2 p0 P: ^
  14.         })' E% o( V% ]' E9 A- ~/ R
  15.     })
    * F9 M+ v9 D* h
  16.   }+ @* ~' P' R  q: X5 T

  17.   d: J# {- @* u2 @& W
复制代码
接口请求成功后,会返回登录标识---sid% V/ O4 a) w  {6 k1 e" D) g
1.png
; y7 u  C: K+ N7 O) j  x
三、群晖上传
群晖上传,也就到了需求最关键的一步
  1. /**4 d+ @1 y" S, ?; `- j
  2.    * @descitption 群晖文件上传# ~/ ?; |6 @: ~" r$ Z0 j
  3.    * @param {String} token token: o5 ?3 R6 F9 F0 e
  4.    * @param {String} path 文件路径# O) M. t0 Q# X' D9 N
  5.    * @param {String} file 文件
    ; }+ ^1 {/ K3 T4 }
  6.    * @param {String} filename 文件名 / `% M* U- o2 s# C! V0 H' s
  7.    * @param {String} create_parents 如果不存在,则创建父文件夹 4 \1 M2 G/ X) v8 }, ~, X
  8.    */) n# X2 f' j7 n9 @! c
  9.   qunhuiUpload(token, path, file, filename) {
    ) b. Q& p7 l+ m
  10.     return new Promise((resolve, reject) => {
    ! ~* l- ?) r$ k4 u% P
  11.       let formData = new FormData()& `" X  E! K% `" }
  12.       formData.append('path', path)7 b, q" F2 G% ^* }
  13.       formData.append('create_parents', false)
    ! d% j, S5 q, p3 L0 a
  14.       formData.append('file', file)
    7 \+ e6 v  X* x5 ~9 w
  15.       formData.append('filename', filename)6 A! \! s* P; X( @0 G  n& ?) _
  16.       axios.post(`接口域名地址/webapi/entry.cgi?api=SYNO.FileStation.Upload&method=upload&version=2&_sid=${token}`, formData)
    ' {/ y. u4 J& i% W0 K
  17.         .then(res => {6 w" n6 Q8 s. l" S
  18.           resolve(res.data)6 u) D  U  y7 s1 z! J
  19.         }).catch(err => {1 G( o) }$ x9 p
  20.           reject(err)
    + x& \" ?, g0 M1 h+ M7 E, q+ L
  21.         })8 [" \$ d9 c2 v" w: o0 r& f; C
  22.     })' N9 |1 [6 E4 w& m% Q
  23.   }6 v3 m) b6 h/ E: U' @0 d
  24. ) q& X# ]% d2 k5 ]# L0 X; C
  25. ) Q" l! y  |. q' B5 r* w- u7 \
复制代码
文件上传接口成功后,并不会返回文件的具体信息,只会包含文件名称等信息
四、获取图片缩略图
上传完成图片后,需要展示图片缩略图,则需要通过接口获取到缩略图文件,获取到的是二进制文件,前端还须在请求时使用blob
  1. /**
    : W% o9 Q7 s/ G; n" ?- f
  2.    * @descitption 获取缩略图
    5 }7 l6 W6 n* {( M7 G0 @) _+ C
  3.    * @param {String} path 文件路径
    ( e# f9 [3 P9 t' y9 W6 k
  4.    * @param {String} filename 文件名
    ' s9 o. p- z& G5 S% i* u
  5.    * @param {String} token token
    ) @& `) a+ \# E
  6.    */! L& ^4 ~1 W! F5 e' @
  7.   getThumbUrl(path, filename, token) {1 o3 ]* P( R- `! |1 Z2 ]1 q
  8.     return new Promise((resolve, reject) => {6 S9 S: K$ n! i8 V) r- t7 l
  9.       axios.get(`接口域名地址/webapi/entry.cgi?api=SYNO.FileStation.Thumb&version=2&method=get&path=${path}/${filename}&_sid=${token}`, {
    ! e4 Y  ?  @/ }' D& r
  10.         responseType: 'blob'
    ( ^! _) c$ C0 w. w
  11.       }).then(res => {" }& H  C* G- \
  12.         const thumbUrl = window.URL.createObjectURL(res.data) // 将二进制文件转为正常文件
    " i# B( P- e, W$ h
  13.         resolve(thumbUrl)2 b# s, w" |8 O5 g! D) ~' ?4 \
  14.       }).catch(err => {1 V7 @& k% e+ j' S% i& d/ `- o
  15.         reject(err)
    ( D! R! Q) U$ p
  16.       })
    % @6 g% J# N/ c' g+ E% z& h0 _
  17.     })
    # o% i. z* X7 R6 P3 e* }0 \
  18.   }
复制代码
五、获取源文件
上传视频等文件时,需要通过接口拿到源文件(也是二进制文件),文档上表示下载接口,但也仅仅是拿到源文件地址,下载功能还需前端自己写js
  1. /**
    9 B$ B# v8 X3 H: e. o9 ]0 ]* g! r1 j
  2.    * @descitption 获取到下载的源文件: \$ X, ]" t* b% _& N& p
  3.    * @param {String} path 文件路径 ! e* p6 U2 F+ X7 Q
  4.    * @param {String} filename 文件名
    : Q% q& u$ x+ s. p; Y
  5.    * @param {String} token token& Z( ~1 [: q0 g0 b5 [" k, V
  6.    */. O0 W7 E1 o$ I- c4 O
  7.   getSourceFile(path, filename, token) {
    ( A8 {5 W: A# ^# @5 D
  8.     return new Promise((resolve, reject) => {
    : r# ^6 R0 ^# P3 k; l
  9.       axios.get(`接口域名地址/webapi/entry.cgi?api=SYNO.FileStation.Download&version=2&method=download&path=${path}/${filename}&_sid=${token}`, {
    / g$ z1 S( {' u" |3 b) w
  10.         responseType: 'blob'1 A* [- w: _6 O4 K) x9 F& |6 N
  11.       }).then(res => {
    7 Y, I7 U  s/ _+ s
  12.         const objectURL = window.URL.createObjectURL(res.data)* V, ?* A3 s* D
  13.         resolve(objectURL)0 \$ Q5 |& ?2 _* N
  14.         this.hook.onSuccess(objectURL)
    6 T7 k: i& q' @* P' ]1 j; }0 y
  15.       }).catch(err => {7 k2 h$ Z1 N* j+ [  L
  16.         reject(err)7 z+ l' y$ g  \
  17.       })' S+ u6 ?0 T, D# l7 O! ]
  18.     })
    $ ~" Z- o2 M0 c+ @( A- `4 G
  19.   }
    . U# w( X" c* ^: t, l$ T* t% |/ o

  20. ' k9 r1 W" }; J, E  E. B6 Z
  21. ; J! p# C4 b- [% i+ g5 i4 s
复制代码
六、创建文件夹
群晖接口也支持通过接口创建新的文件夹
  1. **
    6 x) h( F8 Q" z
  2.    * @descitption 创建文件夹
    . r- Z5 o* b2 F6 \; X
  3.    * @param {String} path 文件夹路径
    * {% d9 c5 i& K- z: t/ J4 U. f
  4.    * @param {String} name 需要创建文件夹的名称
    0 S4 m3 I7 R9 _1 M( k
  5.    */
    7 j" S+ A- z  o& ^$ _
  6.   createFolder(path, name, token) {
    1 W8 D, v: L5 K7 q0 N8 @
  7.     return new Promise((resolve, reject) => {
    ! M2 }/ X9 J# L( J2 L5 t0 ^; b7 A
  8.       axios.get(`接口域名地址/webapi/entry.cgi?api=SYNO.FileStation.CreateFolder&version=2&method=create&force_parent=true&folder_path=${path}&name=${name}&_sid=${token}`).then(res => {4 F, k& [( x5 a3 ?: m1 b( |9 o7 P
  9.         resolve(res.data)% W( r/ B2 b; S! Q
  10.       }).catch(err => {) g7 A% Y& z# }9 U8 {- V! [- n
  11.         reject(err)
    1 x. B4 T% g, n" |' @2 _; [7 B! |9 K
  12.       })
    # u$ [% i6 Z* v
  13.     })
    1 i8 O& Q5 V/ q% d
  14.   }3 ~  h1 N# s# ^& ]8 i& E- d+ K
复制代码
以上则是构造函数中所需要的一些方法,去实现登录,上传,查看,创建文件夹等,接下来就是如何去调用他,在使用的位置,定义好你需要的配置项,比如方法中需要的账号,密码,文件夹路径,然后去new 一个构造函数。
; n' Y* p2 z; n* a# ^9 K
  1. const hook = {
    : x- S6 Z- J/ N7 ^5 ~3 R; d- E6 z
  2.           onSuccess: (res) => { this.QunHuiSuccess(res) },
    1 R2 Y& d+ Y3 D2 X% j
  3.           onError: (err) => { this.QunHuiError(err) }) }0 m$ ?# R9 _
  4.         }
    5 _8 D& c  ?( W6 K2 g
  5. const data = {
    4 G: x& v5 O" z/ G. T
  6.           account: '账号',  ^. Y( h. t. O- U" \7 y
  7.           password: '密码',' R; [; p* [! t. C! J- m
  8.           folder_path: '文件夹路径'& E! L' f: h5 J( p
  9.       }
    : G8 p$ Z) [& a- i. u
  10. const uploader = new Uploader(file, {}, data, hook)
    ( k% t4 c/ i) M; ?6 N
复制代码
七、错误code
; y7 F) R: V: j1 L
: r+ ~0 x. \  D6 ~  F
. [! Y, j9 V1 R% @9 `
  1. export const code = {% k& T9 u5 Z+ |+ ^
  2.   400: '文件操作的参数无效',' R6 Q) J9 M0 [3 ^
  3.   401: '文件操作的未知错误',% p! |* Q  r! z% x1 X
  4.   402: '系统繁忙',8 l( {7 r7 I" F; l3 u
  5.   403: '用户执行此文件操作时无效',6 k( w# B+ u/ l  }( [
  6.   404: '执行此文件操作的组无效',) F. L0 o0 |9 S5 I: s1 R
  7.   405: '用户和组执行此文件操作无效',
    . Z: Z# v# i0 H1 c$ p- s
  8.   406: '无法从帐户服务器获取用户/组信息',6 {; s( [/ M2 e# X. m
  9.   407: '无操作权限',
    # P2 I3 m$ \7 H+ ^
  10.   408: '没有这样的文件或目录',
    5 b& K0 w7 v* u; p
  11.   409: '不支持的文件系统',
    8 h1 L  Y6 z' s9 ?  W
  12.   410: '连接基于互联网的文件系统',
    ) [6 n3 B6 Z6 `6 H
  13.   411: '只读文件系统',
    & t7 R: V/ K# F
  14.   412: '在非加密的文件系统中使用的文件名太长',% K4 U2 r. j7 ^
  15.   413: '在加密的文件系统中使用的文件名太长',$ N  `, o% p( a5 u3 k  o. F9 I
  16.   414: '文件已存在',8 l# j" e; u4 j! l7 R6 }; r
  17.   415: '内存不够用了',
    : h- }. |8 {3 q9 G; z
  18.   416: '内存不够用了',
    , b* Z' R! H8 v2 N* M+ k: b
  19.   417: '输入输出错误',: U3 t6 J+ m& O, c, [
  20.   418: '非法的名称或路径',
    # Y" y* Q% u! [7 g- T6 e
  21.   419: '非法文件名',' M" A+ q. [1 F9 a0 Q! k
  22.   420: '文件系统上的非法文件名',9 u2 E! R2 X; c2 e5 j
  23.   421: '设备繁忙',
    - _  p3 B+ x( E4 h; x
  24.   599: '文件操作中没有这样的任务'1 T7 f8 @9 W' `' M% D4 c
  25. }$ @# @' [0 k) ^. D+ k3 I/ w4 T& R3 I
复制代码

! O: u4 v1 }; u# K9 [7 A如果要实现群晖上传,首先需要登录拿到群晖的token---sid,上传时将sid带入,包括其余的接口,都需要sid去验证。上传后接口返回的code码可以根据上面列出来的错误做对比进行错误抛出。
做电商找商乾,中国最大的电商技术资源交流中心!
商乾全球电商人、电商交流学习与电商实战技术分享、电商爬虫、生活交流专业网站
  • 官方手机版

  • 微信公众号

  • 商务合作