【JS】文件上传与Koa2

文件上传与Koa2

九月发布于 今天 02:26

前言

本文仅为koa2上传文件(图片/文本/视频/音频)到七牛云的记叙。

关于我是如何找到该文档的?
在没有具体思路前,我也去看了好多博客,但是大家都没有说为什么要按照这个步骤/方法去上传,照着实现,出了问题也不知该从哪方面来解决,甚是气人。但看到大家都用到的一句代码是tiformUploader.putFile(uploadToken, key, localFile, putExtra, function (),就试着在谷歌“七牛云开发者文档”,然后选择比较官方的一个“七牛云开发者中心”,点开网站后一个大大的搜索框,输入上面的那句主要代码,就调整到对应的Nodejs SDK,正是我们所需要的。
下次找相关的官方文档时,就可以用这个方法。

上传的本质

在说具体代码之前,我想先说说在客户端上传的原理,这样你就能理解下面说的几种上传形式其实在本质上都是一样。
我认为的上传的本质一句话就是“获取到文件对象File,将File以表单格式提交到服务器端”。可以转化为两个疑问来讲解:

1. 如何取到文件对象File?

2. 如何以表单格式提交?

如何取到文件对象File:

文件上传元素是:<input type="file" id="input"> , 经type="file"标识,就可以通过 File API访问 FileList,它包含了表示用户所选文件的 File 对象。
type="file"都是以列表(FileList)形式存在,本文章以单文件上传来讲解,取的是FileList中的一个元素。
访问被选择的文件的两种方式:

第一种:`const myFile = document.getElementById('input').files[0]`

第二种:`document.getElementById('input').addEventListener("change", function() { const myFile = this.files[0] }, false)`

myFile 即我们要获取的选择文件的 File 对象。

可参见:
MDN: 在web应用程序中使用文件
MDN: input type="file"

如何以表单格式提交:

文件一般都是用表单格式来提交的,不管我们是上传到七牛云还是上传到自己的服务器上。

web上的http请求都是基于 XMLHttpRequest接口来实现的。而XMLHttpRequest有一个formData接口,支持发送表单数据;FormData 类型的数据,XMLHttpRequest的content-type默认值为multipart/form-data,你也可以手动设置;

我们常用的ajax、axios都是基于XMLHttpRequest封装实现的

可参见:
阮一峰:XMLHttpRequest Level 2 使用指南
MDN:FormData 对象的使用
MDN:FormData

上传方式

文件上传分为 客户端上传 和 服务端上传 两种场景。
文件上传到七牛云,可先查阅七牛的开发者文档。

七牛云配置

在上传之前,先配置好七牛,并拿到以下值:
AccessKey
SecretKey :七牛密钥(个人中心 - 密钥管理)
Bucket :空间名称(对象管理 - 空间管理 - 空间名称)
domain :CDN 域名
zone:存储区域(对应自己主机的区域,可查看 七牛存储区域)

客户端上传

客户端上传是指文件上传到七牛这个动作在前端进行。

服务器端获取七牛token

文件在上传到七牛云时需要带上一个七牛云的上传凭证,即我们说的token,否则会401错误,这个token由服务器来获取。
在拿到七牛的AccessKeySecretKeyBucket后,就可以在服务器端生成token了,如下实现:

var options = {

scope: bucket,

};

var putPolicy = new qiniu.rs.PutPolicy(options);

var uploadToken=putPolicy.uploadToken(mac);

目的是要把 uploadToken 返回给前端。
上面代码是最简单的设置,也可以参照 开发者文档 设置其他参数。

整体思路

  1. 上传前。在上传前需要拿到上传地址(zone)、上传凭证(token)、存储cdn域名(domain);
  2. 上传。把文件和token一起上传;
    2.1 获取到文件对象File
    2.2 上传参数有token、file、key(可选),以POST方法上传到机房,上传请求头为“multipart-formdata”
  3. 上传完成。上传成功后七牛返回一个key和hash,domain拼接上key即可显示图片了,key可以理解为图片在七牛上的资源定位唯一标识。
    3.1 上传成功后七牛返回图片可以是“blob格式”或者“路径格式”。
    3.2 第2.2步中,上传参数加上key值上传成功后即返回图片路径格式。key的格式为“文件名+文件后缀”结尾,前面可以拼接存储路径,如“public/images/a.png”、“public/audios/a.mp3” 。

几个注意点:
a. domain、zone 可以自己写在本地,也可以让后端来返回;
b. token有效期只有一次,再次上传时,不管上传的是否为同一张图片都需要重新拿token;

客户端上传文件

客户端拿到后端返回的token,就可以上传文件了。
客户端上传有几种方式,我分为三种:

  • 接口形式上传
  • 组件形式上传

方式一:接口形式上传

html:

<input type="file" id="avatar" accept="image/png, image/jpeg" />

![](imageUrl)

js:

let input = document.getElementById('avatar')

input.addEventListener('change', async () => {

// 获取File对象

const file = input.files[0]

// 请求后端接口获取到七牛的 domain, zone, token;token有效期只有一次,所以每次上传前都先获取token

const { data: { domain, zone, token } } = await API.getQiniuToken()

if(!token) {

console.log('获取七牛token失败')

return

}

let formdata = new FormData()

formdata.append('token', token)

formdata.append('file', file)

formdata.append('key', `public/tmp/${Date.now()}${file.name.split('.').pop()}`) // key参数可选

axios({

method: 'POST',

url: zone,

data: formdata,

})

.then((response) => {

console.log(response.data)

this.imageUrl = `http://${domain}/${response.data.key}`

})

.catch((error) => {

console.log(error)

})

})

方式二:组件形式

这里以 ElementUI 的上传组件为例。
用 ElementUI 或 iviewUI 的同学应该知道,上传组件可以设置actiondata属性:
action:必选参数,上传的地址。即对应七牛的存储区域zone,组件会自动帮我们上传,上传成功后触发on-success事件;
data: 上传时附带的额外参数。上传到七牛的额外参数需要有:token、file、key(可选)。组件会默认加上file,所以我们只需要带上token(或{token、key})就可以了。

实现过程如下:

<template>

<el-upload

:action="qiniu.zone"

:data="{ token: qiniu.token, key: imageKey }"

:show-file-list="false"

:on-success="success"

:on-error="fail"

:before-upload="beforeUpload">

![](imageUrl)

<button>上传图片:</button>

</el-upload>

</template>

<script>

import { Upload } from 'element-ui'

import { qiniu as API } from '@/api'

export default {

name: 'ImageUploader',

components: {

'el-upload': Upload

},

data () {

return {

imageKey: '',

imageUrl: '',

qiniu: { domain: '', zone: '', token: '' }

}

},

methods: {

async beforeUpload (file) {

// 请求后端接口获取到七牛的 domain, zone, token

const { data } = await API.getQiniuToken()

this.qiniu = data

if(!token) {

console.log('获取七牛token失败')

return

}

// 设置上传的key值,可选

this.imageKey = `public/tmp/${Date.now()}${file.name.split('.').pop()}`

},

success (res, file) {

this.imageUrl = `http://${this.qiniu.domain}/${res.key}`

},

fail (err, file) {

console.log(err)

}

}

}

</script>

下为请求的截图,从图中可以看到,组件也是用 FormData 来进行上传的:
【JS】文件上传与Koa2

服务端上传

服务端上传,其官方说法是:

可参见:七牛云 Node.js SDK - 服务器直传

服务度上传文件到七牛也有几种方法,这里说最简单的一种:上传本地文件,直接指定文件的完整路径即可上传。

先说几个注意点:
koa2获取表单数据是用koa-body实现的。如果 ctx.request.files.file 为 undefined,可以从下面几点排查:

  1. koaBody 需添加 multipart: true 设置;
  2. koa-body版本问题。koa-body v3和v4之前通过ctx.request.body捕获文件。而v3.v4后才是通过ctx.request.files.file进行获取;
  3. koa-bodykoa-bodyparser 冲突。koa2 使用 koa-body 代替 koa-bodyparser 和 koa-multer。koa-bod 与 koa-bodyparser 同时存在时,get请求会发生错误。

  4. 关于中间件顺序问题。路由中间件和koa-body中间件都存在时,koa-body需要在路由之前注入。

        app.use(koaBody({ multipart: true }))

    app.use(router.routes(), router.allowedMethods())

  5. 前端以表单格式formdata提交,用POST方法并设置编码类型 "Content-Type": "multipart/form-data" 。下为axios示例:

    const file = document.getElementById('image_upload').files[0]

let formdata = new FormData()
formdata.append('file', file)

let config = {
headers: { 'Content-Type': 'multipart/form-data' },
}

axios({
method: 'POST',
url: '/upload',
data: formdata,
config
})
.then((response) => console.log(response.data))
.catch((error) => console.log(error))

6. 文件上传到本地时,以流的形式来读取,数据可用之前,读取操作不会结束。这可以防止进程的退出与流的自动关闭。监听读取的`end`事件,读取结束后再进行下一步操作。

下为具体实现:

const qiniu = require('qiniu')
const path = require('path')
const fs = require('fs')
const config = require('../config')
const { bucket, zone, domain, AK, SK } = config.qiniu

static async uploaderAvatar (ctx) {

// 获取上传文件

const file = ctx.request.files.file

// 写入目录

const mkdirsSync = (dirname) => {

if (fs.existsSync(dirname)) {

return true

} else {

if (mkdirsSync(path.dirname(dirname))) {

fs.mkdirSync(dirname)

return true

}

}

return false

}

// 重命名

function rename (fileName) {

return Math.random().toString(16).substr(2) + '.' + fileName.split('.').pop()

}

// 删除文件

function removeTemImage (path) {

fs.unlink(path, (err) => {

if (err) {

throw err

}

})

}

// 上传到本地

/**

* @description 上传到本地

* @param {*} file

* @returns {Promise} fileName fileFullPath

* @file http://nodejs.cn/api/fs.html#fs_fs_createreadstream_path_options

*/

function upToLocal (file) {

return new Promise((resolve, reject) => {

// 本地文件存储路径

let filePath = path.join(__dirname, 'public/upload/');

// 创建本地上传文件路径

const confirm = mkdirsSync(filePath)

if (!confirm) {

console.log("------- 创建本地上传文件路径失败 ----------")

return

}

// 创建可读流

const stream = fs.createReadStream(file.path)

// 文件名

const fileName = rename(file.name)

// 本地文件路径

const fileFullPath = path.join(path.join(filePath, fileName))

// 创建可写流

const upStream = fs.createWriteStream(fileFullPath)

// 可读流通过管道写入可写流

stream.pipe(upStream);

stream.on('end', () => {

console.log('file read finished');

// 关闭流

stream.push(null);

stream.read(0);

resolve({ fileName, fileFullPath })

})

stream.on('error', (err) => {

reject('------------ createReadStream error -----------', err)

})

})

}

// 上传到七牛

/**

* @description 上传到七牛

* @param {String} key

* @param {String} filePath

* @returns {Promise} {hash, key}

* @file https://developer.qiniu.com/kodo/sdk/1289/nodejs

*/

function upToQiniu ({ fileName, fileFullPath }) {

// 参数1:获取token凭证

const mac = new qiniu.auth.digest.Mac(AK, SK)

const options = {

scope: bucket

}

const putPolicy = new qiniu.rs.PutPolicy(options)

const uploadToken = putPolicy.uploadToken(mac)

// 参数2:需要上传到七牛云的文件路径

const key = `public/tem/${fileName}`

// 参数3:上传在本地的临时文件的路径

const localFile = fileFullPath.replace(/\\/g, '\/')

// 参数4:固定参数,额为参数

const putExtra = new qiniu.form_up.PutExtra();

// new 一个七牛云的上传对象

let config = new qiniu.conf.Config();

// Zone_z2为空间对应的机房

config.zone = qiniu.zone.Zone_z2

const formUploader = new qiniu.form_up.FormUploader(config);

// 文件上传到七牛云(单文件)

return new Promise((resolved, reject) => {

/**

* uploadToken 七牛云上传凭证

* key 七牛云文件存储路径

* localFile 本地文件路径

* putExtra 额为参数

*/

formUploader.putFile(uploadToken, key, localFile, putExtra, function (respErr, respBody, respInfo) {

if (respErr) {

reject(respErr)

}

if (respInfo.statusCode == 200) {

resolved(respBody)

} else {

resolved(respBody)

}

})

})

}

// 上传文件到本地获,获取本地的 文件名 和 文件路径

const local_res = await upToLocal(file)

// 文件路径->读取本地文件上传到七牛云;文件名->设置为七牛云的key(可以理解为上传到七牛云后,该key值就是该文件的资源定位唯一标识)

const qn_res = await upToQiniu(local_res)

// 上存到七牛后,删除缓存在本地的图片

removeTemImage(local_res.fileFullPath)

ctx.status = 200

ctx.body = {

code: 0,

message: 'success',

data: {

avatar: `http://${domain}/${qn_res.key}`

}

}

}

javascript前端

阅读 40更新于 今天 02:27

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


web前端开发

前端开发所用技术

avatar

九月

89 声望

0 粉丝

0 条评论

得票时间

avatar

九月

89 声望

0 粉丝

宣传栏

前言

本文仅为koa2上传文件(图片/文本/视频/音频)到七牛云的记叙。

关于我是如何找到该文档的?
在没有具体思路前,我也去看了好多博客,但是大家都没有说为什么要按照这个步骤/方法去上传,照着实现,出了问题也不知该从哪方面来解决,甚是气人。但看到大家都用到的一句代码是tiformUploader.putFile(uploadToken, key, localFile, putExtra, function (),就试着在谷歌“七牛云开发者文档”,然后选择比较官方的一个“七牛云开发者中心”,点开网站后一个大大的搜索框,输入上面的那句主要代码,就调整到对应的Nodejs SDK,正是我们所需要的。
下次找相关的官方文档时,就可以用这个方法。

上传的本质

在说具体代码之前,我想先说说在客户端上传的原理,这样你就能理解下面说的几种上传形式其实在本质上都是一样。
我认为的上传的本质一句话就是“获取到文件对象File,将File以表单格式提交到服务器端”。可以转化为两个疑问来讲解:

1. 如何取到文件对象File?

2. 如何以表单格式提交?

如何取到文件对象File:

文件上传元素是:<input type="file" id="input"> , 经type="file"标识,就可以通过 File API访问 FileList,它包含了表示用户所选文件的 File 对象。
type="file"都是以列表(FileList)形式存在,本文章以单文件上传来讲解,取的是FileList中的一个元素。
访问被选择的文件的两种方式:

第一种:`const myFile = document.getElementById('input').files[0]`

第二种:`document.getElementById('input').addEventListener("change", function() { const myFile = this.files[0] }, false)`

myFile 即我们要获取的选择文件的 File 对象。

可参见:
MDN: 在web应用程序中使用文件
MDN: input type="file"

如何以表单格式提交:

文件一般都是用表单格式来提交的,不管我们是上传到七牛云还是上传到自己的服务器上。

web上的http请求都是基于 XMLHttpRequest接口来实现的。而XMLHttpRequest有一个formData接口,支持发送表单数据;FormData 类型的数据,XMLHttpRequest的content-type默认值为multipart/form-data,你也可以手动设置;

我们常用的ajax、axios都是基于XMLHttpRequest封装实现的

可参见:
阮一峰:XMLHttpRequest Level 2 使用指南
MDN:FormData 对象的使用
MDN:FormData

上传方式

文件上传分为 客户端上传 和 服务端上传 两种场景。
文件上传到七牛云,可先查阅七牛的开发者文档。

七牛云配置

在上传之前,先配置好七牛,并拿到以下值:
AccessKey
SecretKey :七牛密钥(个人中心 - 密钥管理)
Bucket :空间名称(对象管理 - 空间管理 - 空间名称)
domain :CDN 域名
zone:存储区域(对应自己主机的区域,可查看 七牛存储区域)

客户端上传

客户端上传是指文件上传到七牛这个动作在前端进行。

服务器端获取七牛token

文件在上传到七牛云时需要带上一个七牛云的上传凭证,即我们说的token,否则会401错误,这个token由服务器来获取。
在拿到七牛的AccessKeySecretKeyBucket后,就可以在服务器端生成token了,如下实现:

var options = {

scope: bucket,

};

var putPolicy = new qiniu.rs.PutPolicy(options);

var uploadToken=putPolicy.uploadToken(mac);

目的是要把 uploadToken 返回给前端。
上面代码是最简单的设置,也可以参照 开发者文档 设置其他参数。

整体思路

  1. 上传前。在上传前需要拿到上传地址(zone)、上传凭证(token)、存储cdn域名(domain);
  2. 上传。把文件和token一起上传;
    2.1 获取到文件对象File
    2.2 上传参数有token、file、key(可选),以POST方法上传到机房,上传请求头为“multipart-formdata”
  3. 上传完成。上传成功后七牛返回一个key和hash,domain拼接上key即可显示图片了,key可以理解为图片在七牛上的资源定位唯一标识。
    3.1 上传成功后七牛返回图片可以是“blob格式”或者“路径格式”。
    3.2 第2.2步中,上传参数加上key值上传成功后即返回图片路径格式。key的格式为“文件名+文件后缀”结尾,前面可以拼接存储路径,如“public/images/a.png”、“public/audios/a.mp3” 。

几个注意点:
a. domain、zone 可以自己写在本地,也可以让后端来返回;
b. token有效期只有一次,再次上传时,不管上传的是否为同一张图片都需要重新拿token;

客户端上传文件

客户端拿到后端返回的token,就可以上传文件了。
客户端上传有几种方式,我分为三种:

  • 接口形式上传
  • 组件形式上传

方式一:接口形式上传

html:

<input type="file" id="avatar" accept="image/png, image/jpeg" />

![](imageUrl)

js:

let input = document.getElementById('avatar')

input.addEventListener('change', async () => {

// 获取File对象

const file = input.files[0]

// 请求后端接口获取到七牛的 domain, zone, token;token有效期只有一次,所以每次上传前都先获取token

const { data: { domain, zone, token } } = await API.getQiniuToken()

if(!token) {

console.log('获取七牛token失败')

return

}

let formdata = new FormData()

formdata.append('token', token)

formdata.append('file', file)

formdata.append('key', `public/tmp/${Date.now()}${file.name.split('.').pop()}`) // key参数可选

axios({

method: 'POST',

url: zone,

data: formdata,

})

.then((response) => {

console.log(response.data)

this.imageUrl = `http://${domain}/${response.data.key}`

})

.catch((error) => {

console.log(error)

})

})

方式二:组件形式

这里以 ElementUI 的上传组件为例。
用 ElementUI 或 iviewUI 的同学应该知道,上传组件可以设置actiondata属性:
action:必选参数,上传的地址。即对应七牛的存储区域zone,组件会自动帮我们上传,上传成功后触发on-success事件;
data: 上传时附带的额外参数。上传到七牛的额外参数需要有:token、file、key(可选)。组件会默认加上file,所以我们只需要带上token(或{token、key})就可以了。

实现过程如下:

<template>

<el-upload

:action="qiniu.zone"

:data="{ token: qiniu.token, key: imageKey }"

:show-file-list="false"

:on-success="success"

:on-error="fail"

:before-upload="beforeUpload">

![](imageUrl)

<button>上传图片:</button>

</el-upload>

</template>

<script>

import { Upload } from 'element-ui'

import { qiniu as API } from '@/api'

export default {

name: 'ImageUploader',

components: {

'el-upload': Upload

},

data () {

return {

imageKey: '',

imageUrl: '',

qiniu: { domain: '', zone: '', token: '' }

}

},

methods: {

async beforeUpload (file) {

// 请求后端接口获取到七牛的 domain, zone, token

const { data } = await API.getQiniuToken()

this.qiniu = data

if(!token) {

console.log('获取七牛token失败')

return

}

// 设置上传的key值,可选

this.imageKey = `public/tmp/${Date.now()}${file.name.split('.').pop()}`

},

success (res, file) {

this.imageUrl = `http://${this.qiniu.domain}/${res.key}`

},

fail (err, file) {

console.log(err)

}

}

}

</script>

下为请求的截图,从图中可以看到,组件也是用 FormData 来进行上传的:
【JS】文件上传与Koa2

服务端上传

服务端上传,其官方说法是:

可参见:七牛云 Node.js SDK - 服务器直传

服务度上传文件到七牛也有几种方法,这里说最简单的一种:上传本地文件,直接指定文件的完整路径即可上传。

先说几个注意点:
koa2获取表单数据是用koa-body实现的。如果 ctx.request.files.file 为 undefined,可以从下面几点排查:

  1. koaBody 需添加 multipart: true 设置;
  2. koa-body版本问题。koa-body v3和v4之前通过ctx.request.body捕获文件。而v3.v4后才是通过ctx.request.files.file进行获取;
  3. koa-bodykoa-bodyparser 冲突。koa2 使用 koa-body 代替 koa-bodyparser 和 koa-multer。koa-bod 与 koa-bodyparser 同时存在时,get请求会发生错误。

  4. 关于中间件顺序问题。路由中间件和koa-body中间件都存在时,koa-body需要在路由之前注入。

        app.use(koaBody({ multipart: true }))

    app.use(router.routes(), router.allowedMethods())

  5. 前端以表单格式formdata提交,用POST方法并设置编码类型 "Content-Type": "multipart/form-data" 。下为axios示例:

    const file = document.getElementById('image_upload').files[0]

let formdata = new FormData()
formdata.append('file', file)

let config = {
headers: { 'Content-Type': 'multipart/form-data' },
}

axios({
method: 'POST',
url: '/upload',
data: formdata,
config
})
.then((response) => console.log(response.data))
.catch((error) => console.log(error))

6. 文件上传到本地时,以流的形式来读取,数据可用之前,读取操作不会结束。这可以防止进程的退出与流的自动关闭。监听读取的`end`事件,读取结束后再进行下一步操作。

下为具体实现:

const qiniu = require('qiniu')
const path = require('path')
const fs = require('fs')
const config = require('../config')
const { bucket, zone, domain, AK, SK } = config.qiniu

static async uploaderAvatar (ctx) {

// 获取上传文件

const file = ctx.request.files.file

// 写入目录

const mkdirsSync = (dirname) => {

if (fs.existsSync(dirname)) {

return true

} else {

if (mkdirsSync(path.dirname(dirname))) {

fs.mkdirSync(dirname)

return true

}

}

return false

}

// 重命名

function rename (fileName) {

return Math.random().toString(16).substr(2) + '.' + fileName.split('.').pop()

}

// 删除文件

function removeTemImage (path) {

fs.unlink(path, (err) => {

if (err) {

throw err

}

})

}

// 上传到本地

/**

* @description 上传到本地

* @param {*} file

* @returns {Promise} fileName fileFullPath

* @file http://nodejs.cn/api/fs.html#fs_fs_createreadstream_path_options

*/

function upToLocal (file) {

return new Promise((resolve, reject) => {

// 本地文件存储路径

let filePath = path.join(__dirname, 'public/upload/');

// 创建本地上传文件路径

const confirm = mkdirsSync(filePath)

if (!confirm) {

console.log("------- 创建本地上传文件路径失败 ----------")

return

}

// 创建可读流

const stream = fs.createReadStream(file.path)

// 文件名

const fileName = rename(file.name)

// 本地文件路径

const fileFullPath = path.join(path.join(filePath, fileName))

// 创建可写流

const upStream = fs.createWriteStream(fileFullPath)

// 可读流通过管道写入可写流

stream.pipe(upStream);

stream.on('end', () => {

console.log('file read finished');

// 关闭流

stream.push(null);

stream.read(0);

resolve({ fileName, fileFullPath })

})

stream.on('error', (err) => {

reject('------------ createReadStream error -----------', err)

})

})

}

// 上传到七牛

/**

* @description 上传到七牛

* @param {String} key

* @param {String} filePath

* @returns {Promise} {hash, key}

* @file https://developer.qiniu.com/kodo/sdk/1289/nodejs

*/

function upToQiniu ({ fileName, fileFullPath }) {

// 参数1:获取token凭证

const mac = new qiniu.auth.digest.Mac(AK, SK)

const options = {

scope: bucket

}

const putPolicy = new qiniu.rs.PutPolicy(options)

const uploadToken = putPolicy.uploadToken(mac)

// 参数2:需要上传到七牛云的文件路径

const key = `public/tem/${fileName}`

// 参数3:上传在本地的临时文件的路径

const localFile = fileFullPath.replace(/\\/g, '\/')

// 参数4:固定参数,额为参数

const putExtra = new qiniu.form_up.PutExtra();

// new 一个七牛云的上传对象

let config = new qiniu.conf.Config();

// Zone_z2为空间对应的机房

config.zone = qiniu.zone.Zone_z2

const formUploader = new qiniu.form_up.FormUploader(config);

// 文件上传到七牛云(单文件)

return new Promise((resolved, reject) => {

/**

* uploadToken 七牛云上传凭证

* key 七牛云文件存储路径

* localFile 本地文件路径

* putExtra 额为参数

*/

formUploader.putFile(uploadToken, key, localFile, putExtra, function (respErr, respBody, respInfo) {

if (respErr) {

reject(respErr)

}

if (respInfo.statusCode == 200) {

resolved(respBody)

} else {

resolved(respBody)

}

})

})

}

// 上传文件到本地获,获取本地的 文件名 和 文件路径

const local_res = await upToLocal(file)

// 文件路径->读取本地文件上传到七牛云;文件名->设置为七牛云的key(可以理解为上传到七牛云后,该key值就是该文件的资源定位唯一标识)

const qn_res = await upToQiniu(local_res)

// 上存到七牛后,删除缓存在本地的图片

removeTemImage(local_res.fileFullPath)

ctx.status = 200

ctx.body = {

code: 0,

message: 'success',

data: {

avatar: `http://${domain}/${qn_res.key}`

}

}

}

以上是 【JS】文件上传与Koa2 的全部内容, 来源链接: utcz.com/a/111426.html

回到顶部