koa2-note
koa2-note copied to clipboard
upload方法监听不到file上传方法
` Request Headers: Accept: / Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: keep-alive Content-Length: 1243 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0nc6DwwRlVIQdGiJ Cookie: captcha_token=408f7903a848baed9d5878f16cb73844; USER_SID=lCyHKbOwfu6Kle9RdT37AUW3mAHzp-BR Host: localhost:8000 Origin: http://localhost:8000 Referer: http://localhost:8000/ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 X-Requested-With: XMLHttpRequest
Request payload
------WebKitFormBoundary0nc6DwwRlVIQdGiJ Content-Disposition: form-data; name="file"; filename="[email protected]" Content-Type: image/png
------WebKitFormBoundary0nc6DwwRlVIQdGiJ-- ` 文件上传前端上传的数据是这样的
服务端用的koa2,上传方法是你的uploadFile方法,但是在调用的时候
// 解析请求文件事件 busboy.on('file', )这个方法并不会触发,我暂时还不知道如何解决,能否给予帮助,谢谢
请问,能否把完整的代码贴出来么?这样子信息太少了
好的,麻烦了,我等明天早上回复,我研究了一段时间还是不知道问题出在哪
` //麻烦了,这里是前端部分代码 用的是ant design的upload组件
<Upload
name="file"
action="http://localhost:8000/api/goods/imgUpload"
accept="image/*"
data={(file)=>{this.upload(file)}}
withCredentials
listType="picture-card"
fileList={fileList}
onPreview={this.handlePreview}
onChange={this.handleChange}
>
{fileList.length >= 10 ? null : uploadButton}
</Upload>
//点击上传后 Request Header
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 814
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZvGXdj5g8yvDOCFD
Cookie: USER_SID=qIk6gw9xjGBH4dnZSiID6ay4H7fMzyzA
Host: localhost:8000
Origin: http://localhost:8000
Referer: http://localhost:8000/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
X-Requested-With: XMLHttpRequest
//发现upload组件上传的信息在 request payload里面
------WebKitFormBoundaryZvGXdj5g8yvDOCFD
Content-Disposition: form-data; name="file"; filename="jiekuan_beika.png"
Content-Type: image/png
------WebKitFormBoundaryZvGXdj5g8yvDOCFD--
//这里是node koa2的主入口app.js
require("babel-register");
require("babel-polyfill");
const path = require('path')
const Koa = require('koa')
const convert = require('koa-convert')
const views = require('koa-views')
const koaStatic = require('koa-static')
const bodyParser = require('koa-bodyparser')
const koaLogger = require('koa-logger')
const session = require('koa-session-minimal')
const MysqlStore = require('koa-mysql-session')
const json = require('koa-json')
const koaBody = require('koa-body');
const errorHandle = require('./controllers/error-catch')
const config = require('./../config')
const routers = require('./routers/index')
const app = new Koa()
// session存储配置
const sessionMysqlConfig = {
user: config.database.USERNAME,
password: config.database.PASSWORD,
database: config.database.DATABASE,
host: config.database.HOST,
}
//配置错误处理中间件
app.use(errorHandle())
// 配置session中间件
const THIRTY_MINTUES = 30 * 60 * 1000;
const staticPath = "static";
app.use(session({
key: 'USER_SID',
store: new MysqlStore(sessionMysqlConfig),
cookie: {
maxAge: THIRTY_MINTUES,
overwrite: false,
rolling: true, //每次api请求是否重置session有效期 默认为fale
renew: false,
}
}))
app.use(koaStatic(
path.join( __dirname, staticPath)
))
// 配置控制台日志中间件
app.use(koaLogger())
// 配置ctx.body解析中间件
app.use(koaBody());
app.use(bodyParser(
{
enableTypes: ['json', 'form', 'text']
}
))
//配置json解析中间件
app.use(json())
// 初始化路由中间件
app.use(routers.routes()).use(routers.allowedMethods())
// 监听启动端口
app.listen(config.port)
console.log(`the server is start at port ${config.port}`)
//上传图片API在controllers里面
router.post('/goods/imgUpload',goodsController.imgUpload )
/**
* 上传商品图片 2018-07-06
* @param {obejct} ctx 上下文对象
*/
async imgUpload(ctx, next) {
let result = new WebResult(ctx.request);
let response = await uploadFile(ctx,{});
if(response.success){
result.set(1,'调用成功')
}
ctx.body = response
}
//这里是upload主要方法
const inspect = require('util').inspect
const path = require('path')
const os = require('os')
const fs = require('fs')
const UtilType = require('./type')
const UtilDatetime = require('./datetime')
const Busboy = require('busboy')
import Appconfig from '../../appConfig'
/**
* 同步创建文件目录
* @param {string} dirname 目录绝对地址
* @return {boolean} 创建目录结果
*/
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname)
return true
}
}
}
/**
* 获取上传文件的后缀名
* @param {string} fileName 获取上传文件的后缀名
* @return {string} 文件后缀名
*/
function getSuffixName(fileName) {
let nameList = fileName.split('.')
return nameList[nameList.length - 1]
}
/**
* 上传文件
* @param {object} ctx koa上下文
* @param {object} options 文件上传参数 fileType文件类型, path文件存放路径
* @return {promise}
*/
function uploadFile(ctx, options) {
let req = ctx.req
let res = ctx.res
let busboy = new Busboy({
headers: req.headers,
})
// 获取类型
let fileType = options.fileType || 'common'
//创建路径
let filePath = path.join(
__dirname,
'/../../server/static/upload/',
fileType,
UtilDatetime.parseStampToFormat(null, 'YYYY/MM/DD')
)
let mkdirResult = mkdirsSync(filePath)
return new Promise((resolve, reject) => {
let result = {
code: -1,
success: false,
message: '',
data: null,
}
// 解析请求文件事件
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
console.log('文件上传中...')
let fileName = Math.random().toString(16).substr(2) + '.' + getSuffixName(filename)
let _uploadFilePath = path.join(filePath, fileName)
let saveTo = path.join(_uploadFilePath)
// 文件保存到制定路径
file.pipe(fs.createWriteStream(saveTo))
// 文件写入事件结束
file.on('end', function () {
result.success = true
result.message = '文件上传成功'
result.data = {
pictureUrl: `//${ctx.host}/image/${fileType}/${fileName}`
}
console.log('文件上传成功!')
resolve(result)
})
})
// 解析表单中其他字段信息
busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('表单字段数据 [' + fieldname + ']: value: ' + inspect(val));
result.data[fieldname] = inspect(val);
});
// 解析结束事件
busboy.on('finish', function () {
console.log('文件上传结束')
resolve(result)
})
// 解析错误事件
busboy.on('error', function (err) {
console.log('文件上出错')
reject(result)
})
//将流链接到busboy对象
req.pipe(busboy);
})
}
module.exports = {
uploadFile
}
现在的问题就是在上传的时候,前端构造的上传数据我认为是正确的,但是去koa2接收的时候,直接输出了文件上传结束,实际是文件夹创建成功,但是图片没有上传成功,好像ctx里面并没有读取到上传的信息
//这里是busboy输出结果
Busboy {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: true,
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
_done: false,
_parser:
Multipart {
_needDrain: false,
_pause: false,
_cb: undefined,
_nparts: 0,
_boy: [Circular],
parser:
Dicer {
_writableState: [Object],
writable: true,
domain: null,
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
_bparser: [Object],
_headerFirst: undefined,
_dashes: 0,
_parts: 0,
_finished: false,
_realFinish: false,
_isPreamble: true,
_justMatched: false,
_firstWrite: true,
_inHeader: true,
_part: undefined,
_cb: undefined,
_ignoreData: false,
_partOpts: {},
_pause: false,
_hparser: [Object] } },
_finished: false,
opts:
{ headers:
{ origin: 'http://localhost:8000',
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryNElS5SQ4CTXinRrG',
accept: '*/*',
referer: 'http://localhost:8000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
cookie: 'USER_SID=qIk6gw9xjGBH4dnZSiID6ay4H7fMzyzA',
connection: 'close',
'content-length': '2',
'accept-charset': 'utf-8',
host: 'localhost:3001' } } }
我猜测是不是busboy与koa-bodyParse解析中间件冲突了 ,导致文件上传失败?
busboy 与koa-body 是冲突的,可以试试在app.js 中注释掉koa-body,就可以正常回调 file 方法了。如果使用了koa-body,可以直接使用它来实现上传功能,不需要再使用busboy了。