Nodejs Express和文件上传

发布于 2024-11-15 13:32:22 字数 1405 浏览 1 评论 0原文

好吧,我已经尝试过使用 connect-form ,但由于某种原因我无法让它工作,但我想我应该从头开始理解它是如何工作的。

我不明白我上传的 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 var 是 req 标头,主体为空。 (可能应该是我理解的)。但我不明白的是文件数据在哪里?寻找我认为的 $_FILES 数组的 php 等效项。 -- 这是我记录的标题。

'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' }

任何关于我所缺少的东西的线索都一如既往地受到高度赞赏!

Ok so ive already tried using connect-form and I couldnt get it working for some reason, but I figure I should understand how this works semi from scratch regardless.

I dont understand where the multipart/formdata file which I am uploaded is going, or how I can access it in my app when its posted to the url. -- Id like to access the file data directy, and write the file output using the node fs module. -- For instance:

    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>');
    });

So the only req var that is actually being logged there is the req headers, body is empty. (probably supposed to be I understand that). But what I dont get is where is the file data? Looking for the php equiv of the $_FILES array I supposed. -- Here is my headers logged.

'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' }

Any light shed upon what Im missing as always much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何处潇湘 2024-11-22 13:32:22

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

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);

Here is very verbose version without connect-form. As you can see, this is not efficient but trying to be instructive about how it works.

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);
早茶月光 2024-11-22 13:32:22

从示例库运行此代码片段怎么样?

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

对我来说效果很好......

How about running this snippet from the example library?

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

works fine for me...

夏雨凉 2024-11-22 13:32:22

我终于能够让 connect-form 包工作了,菜鸟错误,但是,如果您使用的是 Express,请确保告诉应用程序在配置函数 app.configure(function(){ 中使用表单模块
app.use(form({ keepExtensions: true }));

(在帖子中它将位于 files.yourfileuploadfieldname.filename 变量中)

——话虽如此,我仍然有兴趣知道如何从头开始,没有连接形式,如果它不是非常难以解释的话。

I was able to get the connect-form package working finally, rookie mistake but, if you are using express make sure you tell the app to use the form module within your config function app.configure(function(){
app.use(form({ keepExtensions: true }));

(the in the post it will be in the files.yourfileuploadfieldname.filename variable)

-- with that said Im still interested to know how to do it from scratch, without connect-form, if its not incredibly difficult to explain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文