problem description
the front end uses the upload component of ant to upload images, the back end uses the service built by koa2 framework, and the front end uses nigix reverse proxy port 8000 to port 3001. Other get,post requests are normal.
the request request status returned after using the upload component is 200, but the backend does not successfully generate the picture.
< hr >upload component method
<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>
< hr >
Requset Header format is as follows
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
< hr >
Requset payload format is as follows
------WebKitFormBoundaryZvGXdj5g8yvDOCFD
Content-Disposition: form-data; name="file"; filename="jiekuan_beika.png"
Content-Type: image/png
------WebKitFormBoundaryZvGXdj5g8yvDOCFD--
< hr >
koa2 app.js file is as follows
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, //apisession fale
renew: false,
}
}))
app.use(koaStatic(
path.join( __dirname, staticPath)
))
//
app.use(koaLogger())
// ctx.body
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}`)
< hr >
the format of the background receiving interface is as follows
router.post("/goods/imgUpload",goodsController.imgUpload )
imgUpload method
async imgUpload(ctx, next) {
let result = new WebResult(ctx.request);
let response = await uploadFile(ctx);
if(response.success){
result.set(1,"")
}
ctx.body = response
}
uploadFile method
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) {
let req = ctx.req
let res = ctx.res
//
if (!/multipart\/form-data/i.test(req.headers["content-type"])) {
return
}
let busboy = new Busboy({headers: req.headers})
//
let fileType = "upload"
//
let filePath = path.join(
__dirname,
"/../static/",
fileType,
UtilDatetime.parseStampToFormat(null, "YYYY/MM/DD")
)
let mkdirResult = mkdirsSync(filePath)
console.log("...")
return new Promise((resolve, reject) => {
let result = {
code: -1,
success: false,
message: "",
data: null,
}
console.log(busboy)
//
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}/upload/${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("")
result.message = ""
resolve(result)
})
//
busboy.on("error", function (err) {
console.log("")
reject(result)
})
//busboy
req.pipe(busboy);
})
}
module.exports = {
uploadFile
}
browsing the official busboy documents and github found that the uploadFile method is consistent with the official, but in the actual operation, only the busboy.on ("finish") method will be triggered, indicating that the file has been uploaded, but the busboy.on (" file") method will not be triggered, that is, the selected file has not actually been uploaded to the local server. After several days of study, I still have no clue. I hope someone can help me. Thank you.