简体   繁体   中英

Error with multipart/form-data in express.js running on Azure

So I've got an express site running on Windows Azure. I'm currently having problems submitting forms that are marked as enctype="multipart/form-data".

The error I'm getting in the logs is: TypeError: Object # has no method 'tmpDir'

When running natively (initiated via node.exe) it works absolutely fine, its only when using the AzureEmulator or on Azure itself it fails.

Now I expect this has something to do with Azure's infrastructure, but I'm wondering whether anyone has managed to work around this?

So a multi-pronged issue here, I'll explain my findings as best as possible, please bear with me.

Connect uses node-formidable for its multipart form parsing, specifically the IncomingForm class. In the constructor of IncomingForm it sets the upload directory to be that of the parameter you pass in, or defaults to the Operating System's temp directory, defined by os.tmpDir(). However, this method is missing from the Windows implementation of node's "os" module.

After reading copious posts, threads etc, I discovered that you should be able to get around this, you need to set the uploadDir property of the bodyParser.

app.use(express.bodyParser({ uploadDir: 'path/to/dir' }));

However there is (at the time of writing) a bug in connect's implementation of multipart forms processing in that it creates an object of IncomingForm without passing any parameters into the constructor, and then setting the properties further down:

var form = new formidable.IncomingForm
    , data = {}
    , files = {}
    , done;

  Object.keys(options).forEach(function(key){
    form[key] = options[key];
  });

So I've forked both express & connect and updating the code to read as:

var form = new formidable.IncomingForm(options)
    , data = {}
    , files = {}
    , done;

  Object.keys(options).forEach(function(key){
    form[key] = options[key];
  });

You can find the forked versions here: not a shameless plug

Fix for Windows Environments (Azure web sites + node.js application).

server.js:

Make sure it does not set an upload dir or tmp dir

app.use(express.bodyParser());

packages.json:

Force node 0.10.21 or above:

"engines": { "node": "v0.10.24" }

Force express 3.4.8 or above:

"express": "3.4.8"

This should update your node to the fixed lib versions and the problem should be gone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM