2011-06-16 52 views
4

好吧,所以我已经尝试使用连接形式,我不能让它工作出于某种原因,但我想我应该明白这是如何工作从零开始无论。nodejs表达和文件上传

我不明白我上传的multipart/formdata文件在哪里,或者我的应用程序何时可以在发布到url时访问它。 - 我喜欢直接访问文件数据,并使用节点fs模块写入文件输出。 - 例如:

app.post('/testy', function(req, res){ 
     console.log(req.body); 
     console.log(req.headers); 
     res.redirect('back'); 

    }); 

    app.get('/testy', function(req, res){ 
     res.send('<form method="post" action="/testy" enctype="multipart/form-data">' 
     + '<p>Image: <input type="file" name="test" /></p>' 
     + '<p><input type="submit" value="Upload" /></p>' 
     + '</form>'); 
    }); 

所以这实际上是被记录的存在REQ头的唯一REQ无功,身体是空的。 (可能应该是我明白这一点)。但我没有得到的是文件数据在哪里?寻找我所假设的$ _FILES数组的PHP equiv。 - 这是我的头文件。

'accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 
'accept-language': 'en-us,en;q=0.5', 
'accept-encoding': 'gzip,deflate', 
'accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 
'keep-alive': '115', 
connection: 'keep-alive', 
referer: 'http://127.0.0.1:3000/testy', 
cookie: 'connect.sid=lDRpluTxjUJeuTmkXlybrYeZ.JYTB155s2DGce2dsyfv1Op5ISCY8uqyqJZK8NjlZ5jM; socketio=flashsocket', 
'x-insight': 'activate', 
'content-type': 'multipart/form-data; boundary=---------------------------5856401949371863571646035001', 
'content-length': '30128' } 

任何灯都流失了我一直非常感谢的失踪!

回答

11

这里是非常详细的版本,没有连接形式。正如你所看到的,这样做效率不高,但试图对它的工作方式提供指导。

var express = require('express'), 
    fs = require('fs'); 
    app = express.createServer(); 

app.post('/testy', function(req, res){ 
    var body = ''; 
    var header = ''; 
    var content_type = req.headers['content-type']; 
    var boundary = content_type.split('; ')[1].split('=')[1]; 
    var content_length = parseInt(req.headers['content-length']); 
    var headerFlag = true; 
    var filename = 'dummy.bin'; 
    var filenameRegexp = /filename="(.*)"/m; 
    console.log('content-type: ' + content_type); 
    console.log('boundary: ' + boundary); 
    console.log('content-length: ' + content_length); 

    req.on('data', function(raw) { 
    console.log('received data length: ' + raw.length); 
    var i = 0; 
    while (i < raw.length) 
     if (headerFlag) { 
     var chars = raw.slice(i, i+4).toString(); 
     if (chars === '\r\n\r\n') { 
      headerFlag = false; 
      header = raw.slice(0, i+4).toString(); 
      console.log('header length: ' + header.length); 
      console.log('header: '); 
      console.log(header); 
      i = i + 4; 
      // get the filename 
      var result = filenameRegexp.exec(header); 
      if (result[1]) { 
      filename = result[1]; 
      } 
      console.log('filename: ' + filename); 
      console.log('header done'); 
     } 
     else { 
      i += 1; 
     } 
     } 
     else { 
     // parsing body including footer 
     body += raw.toString('binary', i, raw.length); 
     i = raw.length; 
     console.log('actual file size: ' + body.length); 
     } 
    }); 

    req.on('end', function() { 
    // removing footer '\r\n'--boundary--\r\n' = (boundary.length + 8) 
    body = body.slice(0, body.length - (boundary.length + 8)) 
    console.log('final file size: ' + body.length); 
    fs.writeFileSync('files/' + filename, body, 'binary'); 
    console.log('done'); 
    res.redirect('back'); 
    }) 
}); 

app.get('/testy', function(req, res){ 
    res.send('<form method="post" action="/testy" enctype="multipart/form-data">' 
      + '<p>Image: <input type="file" name="test" /></p>' 
      + '<p><input type="submit" value="Upload" /></p>' 
      + '</form>'); 
}); 

app.listen(4000); 
+1

要走的路!网络上的许多上传示例不起作用真是令人惊讶。 – 2012-04-30 16:29:11

+0

我不相信这实际上有效!我一直在寻找一个工作! – 2012-08-02 19:36:00

+0

@Cirrostratus它不工作,因为nodejs的API经常变化。这是2011年7月1日写成的,你在9个月后评论了2012年4月30日。 – 2012-10-03 03:04:25

4

如何从示例库运行此代码段?

https://github.com/visionmedia/express/blob/master/examples/multipart/app.js

/** 
* Module dependencies. 
*/ 

var express = require('express') 
    , form = require('connect-form'); 

var app = express.createServer(
    // connect-form (http://github.com/visionmedia/connect-form) 
    // middleware uses the formidable middleware to parse urlencoded 
    // and multipart form data 
    form({ keepExtensions: true }) 
); 

app.get('/', function(req, res){ 
    res.send('<form method="post" enctype="multipart/form-data">' 
    + '<p>Image: <input type="file" name="image" /></p>' 
    + '<p><input type="submit" value="Upload" /></p>' 
    + '</form>'); 
}); 

app.post('/', function(req, res, next){ 

    // connect-form adds the req.form object 
    // we can (optionally) define onComplete, passing 
    // the exception (if any) fields parsed, and files parsed 
    req.form.complete(function(err, fields, files){ 
    if (err) { 
     next(err); 
    } else { 
     console.log('\nuploaded %s to %s' 
     , files.image.filename 
     , files.image.path); 
     res.redirect('back'); 
    } 
    }); 

    // We can add listeners for several form 
    // events such as "progress" 
    req.form.on('progress', function(bytesReceived, bytesExpected){ 
    var percent = (bytesReceived/bytesExpected * 100) | 0; 
    process.stdout.write('Uploading: %' + percent + '\r'); 
    }); 
}); 

app.listen(3000); 
console.log('Express app started on port 3000'); 

npm install express 
npm install connect-form 
node app.js 

工作正常,我...

1

我能得到的连接形式的封装最后的工作,新手的错误,但如果你正在使用快速确保你告诉应用程序使用你的配置功能app.configure(function(){ app.use(form({keepExtensions:true}));

(中后它会在files.yourfileuploadfieldname.filename变量)

- 随着中说我还在想知道如何从头开始做,没有连接形式,如果它不难以置信地难以解释。