Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upload方法监听不到file上传方法 #46

Open
xjl271314 opened this issue Jul 9, 2018 · 5 comments
Open

upload方法监听不到file上传方法 #46

xjl271314 opened this issue Jul 9, 2018 · 5 comments

Comments

@xjl271314
Copy link

`
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', )这个方法并不会触发,我暂时还不知道如何解决,能否给予帮助,谢谢

@chenshenhai
Copy link
Owner

请问,能否把完整的代码贴出来么?这样子信息太少了

@xjl271314
Copy link
Author

好的,麻烦了,我等明天早上回复,我研究了一段时间还是不知道问题出在哪

@xjl271314
Copy link
Author

`
//麻烦了,这里是前端部分代码 用的是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' } } }

@xjl271314
Copy link
Author

我猜测是不是busboy与koa-bodyParse解析中间件冲突了 ,导致文件上传失败?

@xiuxiuing
Copy link

busboy 与koa-body 是冲突的,可以试试在app.js 中注释掉koa-body,就可以正常回调 file 方法了。如果使用了koa-body,可以直接使用它来实现上传功能,不需要再使用busboy了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants