nodejs formidable not triggering any events

孤街浪徒 提交于 2020-01-13 09:44:33

问题


I am on express3.x and using formidable

app.post "/up",(req,res)->
formidable = require('formidable')
form = new formidable.IncomingForm()
form.uploadDir = __dirname + "/uploads"
form.encoding = 'binary'


form.addListener 'file',(name,file) ->
    #write file
    console.log('file uploaded')
    return
console.log('$$$$$$$$$$$')
form.addListener 'end', ->
    console.log('end')
    res.end()
    return
console.log('@@@@@$$$$')
form.parse req,(err,fields,files)->
    console.log('parse')
    console.log(err) if(err)
    return
console.log('######')
return

and the upload form is

block content
:coffeescript
    $ ->
        formData = new FormData()
        xhr = new XMLHttpRequest()
        onProgress = (e)->
            per_complete = (e.loaded/e.total) * 100 if e.lengthComputable

        onReady = (e)->
            alert("Ready")

        onError = (err)->
            alert("Error Loading "+err)

        $('#upload').click (e)->
            formData.append('img',document.getElementById('img').files[0])
            xhr.open('post','/up',true)
            xhr.addEventListener('error',onError,false)
            xhr.addEventListener('progress',onProgress,false)
            xhr.send(formData)
            xhr.addEventListener('readystatechange',onReady,false)

h1 hello world
form
    |select Image: 
    input(type='file',name='img', id='img')
    input(type='button',value='button', id='upload')

none of events are getting triggered...Not sure what am I my missing..


回答1:


if you use app.use(express.bodyParser()) is equivalent to:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());

you can remove app.use(express.multipart()); then you can use formidable object.




回答2:


express is using formidable internally, so your formidable doesn't get any events, if you would like to use formidable on your own you have to remove multipart/form-data from the bodyParser

i am still on express 2.x but that should also do the trick on 3.x, in your app.configure function try

app.configure(function(){
  delete express.bodyParser.parse['multipart/form-data']
})

now you can use formidable on your own.




回答3:


Is there a specific reason why you are using formidable and not the built in bodyParser? It uses the multipart middleware and is based on formidable. Therefore most of the options from formidable can also be applied to the bodyParser. For example:

app.use(connect.multipart({ uploadDir: path }));

To answer your question, try the following code:

app.js

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.post("/", function(req, res) {
  console.log(req.files.img)
  res.end()
})

index.jade

form
  input(type="file", name="img", id="img")
  input(type="button", value="button", id="upload")
script
  var formdata = new FormData()
  var xhr = new XMLHttpRequest()

  $("#upload").on("click", function(e) {            
    xhr.upload.onprogress = function(evt) {
      console.log("While sending and loading data.")
      if (evt.lengthComputable) {
        console.log (evt.loaded / evt.total * 100);
      }
    }

    xhr.onloadend = function(evt) {
      console.log("When the request has completed (either in success or failure).")
    }

    xhr.onload = function(evt) {
      console.log("When the request has successfully completed.")
    }

    var image = document.getElementById('img').files[0]
    formdata.append("img", image)
    xhr.open("POST", "/", true)
    xhr.send(formdata)
  })

Have a look at the W3C Specifications for more events.




回答4:


I had the same issue in which the file was uploaded completly before My controller got arround to proccessing it. The events were fired but I wasn't listening yet. To counter act this I wrote a middleware to capture file uploads and keep them around for controller to access later.

https://gist.github.com/3813103

you can implement it with

var fileHandler = require('./middleware/fileHandler');
app.use(fileHandler());



回答5:


Similar issue happened today.
Wasted 4+ hours of time.
Was expecting an answer here, but din't find it here, so writing it.

Problem

1. formidable - fileBegin event is     fired  
2. formidable - file      event is     fired - for small ~3MB/~4MB files
3. formidable - file      event is not fired - for large files

on local machine - nodejs/libraries will work fine
on remote machine - behind nginx it above issue happens

Libraries used:
- micro - https://github.com/zeit/micro - main culprit due to too easy programming model
- formidable - https://www.npmjs.com/package/formidable - smaller culprit does not give example of async/await

Solution

1. increase the VM memory size 2/3 times the file upload size (libraries eat a lot of memory)
2. increase both proxy & http timeout/ size in the nginx to the required
    - example, 10 mins timeout & 2G size
3. change the programming model for large files
    a. on local machine - nodejs/libraries will work fine
    b. but behind the nginx proxy, it optimizes and kills the on going process asap
        to solve this proxy issue, use more promises/ async-awaits, delay the reply to nginx

Hope that helps.



来源:https://stackoverflow.com/questions/12501410/nodejs-formidable-not-triggering-any-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!