2011-06-16 96 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變量)

- 隨着中說我還在想知道如何從頭開始做,沒有連接形式,如果它不難以置信地難以解釋。