admin管理员组

文章数量:1415697

I have this piece of code:

router.route("/post")
        .get(function(req, res) {
            ...
        })
        .post(authReq, function(req, res) {
            ...
            // Get uploaded file
            var fstream
            req.pipe(req.busboy)
            req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            ...

            var fileSuffix = mimetype.split("/")[1] // Get suffix, may not always be correct
            var tmpFileName = postCount + "." + fileSuffix
            var tmpFileURL = __dirname + "/tmp/" + tmpFileName
            // Start writing
            fstream = fs.createWriteStream(tmpFileURL)
            file.pipe(fstream)
            fstream.on('close', function() {
                 ...
            })
        })
    })
})

This use to work perfectly. However, I don't know quite what happened, but I picked up my puter today and found this error occurring every time I attempt to post:

TypeError: Cannot call method 'on' of undefined
    at IningMessage.Readable.pipe (_stream_readable.js:494:8)
    at /Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:139:8
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at authReq (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:17:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:94:14)
    at Route.dispatch (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)

_stream_readable.js:501
    dest.end();
         ^
TypeError: Cannot call method 'end' of undefined
    at IningMessage.onend (_stream_readable.js:501:10)
    at IningMessage.g (events.js:180:16)
    at IningMessage.emit (events.js:92:17)
    at _stream_readable.js:943:16
    at process._tickCallback (node.js:419:13)

In my index.js file, I have this code to use Busboy:

app.use(busboy())

Then this code to include my route:

app.use("/api", require("./apiRoutes.js")())

Thanks in advance!

EDIT: I was doing a bit more debugging and I think I pinpointed the issue. req.busboy is not defined. So I went digging through source code. Here is some of the code in the connect-busboy module:

if (req.busboy
|| req.method === 'GET'
|| req.method === 'HEAD'
|| !hasBody(req)
|| !RE_MIME.test(mime(req)))
return next()

When I print out the actual values, busboy does not exist, the request method is 'POST', hasBody(req) results true, yet RE_MIME.test(mime(req))) results false, which is why busboy is not added to the request.

My example file's MIME type is image/gif. Here is the regular expression connect-busboy is testing image/gif off of (aka RE_MIME variable):

/^(?:multipart\/.+)|(?:application\/x-www-form-urlencoded)$/i;

Therefore, I've e to the verdict I'm misunderstanding the API. Is Busboy only for HTML forms?

EDIT #2: I simply switched to Multer and it works fine. However, I believe my issue was that I needed to place the file in a multipart part of the request; I'm not sure why it was working before. Thanks!

I have this piece of code:

router.route("/post")
        .get(function(req, res) {
            ...
        })
        .post(authReq, function(req, res) {
            ...
            // Get uploaded file
            var fstream
            req.pipe(req.busboy)
            req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            ...

            var fileSuffix = mimetype.split("/")[1] // Get suffix, may not always be correct
            var tmpFileName = postCount + "." + fileSuffix
            var tmpFileURL = __dirname + "/tmp/" + tmpFileName
            // Start writing
            fstream = fs.createWriteStream(tmpFileURL)
            file.pipe(fstream)
            fstream.on('close', function() {
                 ...
            })
        })
    })
})

This use to work perfectly. However, I don't know quite what happened, but I picked up my puter today and found this error occurring every time I attempt to post:

TypeError: Cannot call method 'on' of undefined
    at IningMessage.Readable.pipe (_stream_readable.js:494:8)
    at /Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:139:8
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at authReq (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/apiRoutes.js:17:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:100:13)
    at next (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:94:14)
    at Route.dispatch (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/nathan/Library/Mobile Documents/~apple~CloudDocs/Dev/LaughItUp/Code/Server/node_modules/express/lib/router/layer.js:82:5)

_stream_readable.js:501
    dest.end();
         ^
TypeError: Cannot call method 'end' of undefined
    at IningMessage.onend (_stream_readable.js:501:10)
    at IningMessage.g (events.js:180:16)
    at IningMessage.emit (events.js:92:17)
    at _stream_readable.js:943:16
    at process._tickCallback (node.js:419:13)

In my index.js file, I have this code to use Busboy:

app.use(busboy())

Then this code to include my route:

app.use("/api", require("./apiRoutes.js")())

Thanks in advance!

EDIT: I was doing a bit more debugging and I think I pinpointed the issue. req.busboy is not defined. So I went digging through source code. Here is some of the code in the connect-busboy module:

if (req.busboy
|| req.method === 'GET'
|| req.method === 'HEAD'
|| !hasBody(req)
|| !RE_MIME.test(mime(req)))
return next()

When I print out the actual values, busboy does not exist, the request method is 'POST', hasBody(req) results true, yet RE_MIME.test(mime(req))) results false, which is why busboy is not added to the request.

My example file's MIME type is image/gif. Here is the regular expression connect-busboy is testing image/gif off of (aka RE_MIME variable):

/^(?:multipart\/.+)|(?:application\/x-www-form-urlencoded)$/i;

Therefore, I've e to the verdict I'm misunderstanding the API. Is Busboy only for HTML forms?

EDIT #2: I simply switched to Multer and it works fine. However, I believe my issue was that I needed to place the file in a multipart part of the request; I'm not sure why it was working before. Thanks!

Share Improve this question edited May 19, 2023 at 18:43 aynber 23k9 gold badges54 silver badges68 bronze badges asked Nov 27, 2014 at 3:22 ZoytZoyt 4,9676 gold badges35 silver badges46 bronze badges 8
  • 1 What does console.dir(req.headers['content-type']) show? – mscdex Commented Nov 27, 2014 at 3:25
  • @mscdex NodeJS doesn't seem to show anything for console.dir, but for console.log, it shows "image/gif" and that's it (since I'm attempting to upload a GIF). – Zoyt Commented Nov 27, 2014 at 3:29
  • where is tmpFileURL? I can't see where you declared it – sadrzadehsina Commented Nov 27, 2014 at 4:52
  • @SinaSadrzadeh - Whoops, I accidentally took out that code. I added that code right before // Start writing. The directory does exist, I checked it. Thanks! – Zoyt Commented Nov 27, 2014 at 5:12
  • I just tried reverting to my last mit, but it still doesn't work. I'm wondering if the Busboy library updated or something. I really don't know what to do from here. – Zoyt Commented Nov 27, 2014 at 7:13
 |  Show 3 more ments

2 Answers 2

Reset to default 4

The problem is that your request is not multipart/form-data, but image/gif instead. Busboy, multer, formidable, multiparty, etc. cannot parse the request unless it's multipart/form-data (if you are uploading a file).

Make sure you have in your index.js file:

var busboy = require('connect-busboy');
// ...
var app = express();
// ...
// and
app.use(busboy()); // I had exact the same error when this line was missing in index.js

本文标签: