使用 Express JS 和 Parse Cloud 托管的图像上传问题

Issues in image upload using Express JS and Parse Cloud hosting

我正在使用托管在 Parse 上的 Cloud Code 和 Express 上传图片。

这是解析日志中的错误:

 I2015-01-03T13:35:55.199Z] TypeError: Cannot read property 'thumbnail' of undefined
    at app.js:40:25
    at callbacks (express_router.js:161:37)
    at param (express_router.js:135:11)
    at pass (express_router.js:142:5)
    at Router._dispatch (express_router.js:170:5)
    at Object.router (express_router.js:33:10)
    at next (connect_proto.js:240:15)
    at Object.expressInit [as handle] (express_middleware.js:31:5)
    at next (connect_proto.js:240:15)
    at Object.query [as handle] (connect_query.js:44:5)

看来 Express JS/Parse 无法理解 req.files.XXX。 app.js 在以下行出现错误:console.error(req.files.thumbnail.size);

此外,req.files 打印以下错误:未提供消息

这里是recipecontent.ejs代码:

<!DOCTYPE html>
<html>
<form method="post" enctype="multipart/form-data" action="/saverecipecontent">
  Enter Recipe Image 1:
  <input type="file" name="thumbnail" id="thumbnail">
  <input type="submit">
</form>

</html>

这里是app.js代码:

// These two lines are required to initialize Express in Cloud Code.
var express = require('express');
var app = express();

// Global app configuration section
app.set('views', 'cloud/views'); // Specify the folder to find templates
app.set('view engine', 'ejs'); // Set the template engine

app.use(express.bodyParser()); // Middleware for reading request body
app.get('/recipecontent', function(req, res) {

  res.render('recipecontent', {
    recipe_name: 'e.g. Rice Cake'
  });
});

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

  console.error(req.files.thumbnail.size);
  console.error(req.files.thumbnail.path);
  console.error(req.files.thumbnail.name);
  console.error(req.files.thumbnail.type);


  Parse.Cloud.run('saveRecipeImage', req.body, {
    success: function(result) {
      // result is 'Hello world!'

    },
    error: function(error) {

    }
  });
});
// Attach the Express app to Cloud Code.
app.listen();

最后是main.js代码:

  require('cloud/app.js');
  Parse.Cloud.define("saveRecipeImage", function(request, response) {

    var recipeContent = Parse.Object.extend("recipe_content");
    var recipeContentObj = new recipeContent();

    console.error(request.params);

    var file = request.params.thumbnail;

    var name = "photo.jpg";

    var parseFile = new Parse.File(name, file);

    parseFile.save().then(function(parseFile) {
      // The file has been saved to Parse.
      var url = parseFile.url();

      recipeContentObj.set("recipe_imgurl1", url);

      return recipeContentObj.save();

    }, function(error) {
      // The file either could not be read, or could not be saved to Parse.

    });


  });

请帮忙!

您似乎在尝试使用 body-parser 中间件来解析 multipar body,但正如 github page of body-parser 本身所述:

This does not handle multipart bodies, due to their complex and typically large nature.

您需要另一个解析器来处理多部分正文。 我建议你 multer 但还有很多其他可用的。

我在 Parse 中提出了这个 bug,这里是更新:

我们支持的中间件express.js不支持文件上传。

您可以做的是将文件内容作为 base64 发送到您的端点,并从该数据创建 Parse.File 对象。

这里是使用文件内容作为端点的 base64 并创建 Parse.File 对象的更新代码:

这里是layout.ejs代码

< html >
  < head >
  < script src = "//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" > < /script>
     <script src="/ / cdnjs.cloudflare.com / ajax / libs / underscore.js / 1.4.4 / underscore - min.js "></script>
    <!--  <% if (locals.title) { %> -->
       <!-- <title><%= title %></title>
     <% } else { %>
       <title>AnyImg</title>
     <% } %> -->
     <link href='//fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
     <script src=" / javascripts / backbone.js "></script>
     <script src="
https: //www.parsecdn.com/js/parse-1.2.8.min.js"></script>
  < script >
  Parse.initialize("n47hKoBkN2vbAAjIPd8rj6Dnc9P6zKYIlXvlZo3x", "a960Z8aOzTNOaKMUcvDQ7lvzT2v2VTHABh6lAdNx"); < /script>
     <script type="text/javascript
" src=" / javascripts / main.js "></script>
  </head>

  <body>
    <div id="
content ">
      <div id="
bar ">
        <h1>File Upload</h1>
      </div>
      
      <div id="
main ">
            <form id="
upload ">
              <div class="
outer ">
                <div>
                  <input type="
text " name="
title " placeholder="
Untitled " />
                  <input id="
asd " type="
file " />
                </div>
              </div>
          </form>
          <img id="
img " src="
" />
          <div id="
base "></div>

      </div>
    </div>
  </body>
</html>

// These two lines are required to initialize Express in Cloud Code.
var express = require('express');
var app = express();

// Global app configuration section
app.set('views', 'cloud/views'); // Specify the folder to find templates
app.set('view engine', 'ejs'); // Set the template engine


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

app.get('/', function(req, res) {

  res.render('layout', {
    recipe_name: 'e.g. Rice Cake'
  });
});

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


  var file = new Parse.File("logo.png", {
    base64: req.body.image
  });

  file.save().then(function() {
    console.log("file saved");

    console.log(file.url());

  });
  if (req.params.image) {
    console.log("data found12345");
  }

});
app.listen();

这是图片js

var base64Data;
var imageName = '';

function readImage(input) {
  if (input.files && input.files[0]) {
    imageName = input.files[0].name;
    var FR = new FileReader();
    FR.onload = function(e) {
      $('#img').attr("src", e.target.result);
      $('#base').text(e.target.result);
      base64Data = e.target.result;
      var datObj = {
        image: e.target.result,
        name: imageName
      };
      var test = {
        image: '12sds'
      };
      $.ajax({
        type: "POST",
        data: datObj,
        url: '/newUploadImage',
        dataType: "json",
        success: function(msg) {
          alert(msg.url);
          console.log();

        },
        error: function(errormsg) {
          console.log(errormsg);
          alert("Sorry, there was an error uploading the image.");
        }
      });

    };
    FR.readAsDataURL(input.files[0]);
  }
}



$(function() {
  // Make all of special links magically post the form
  // when it has a particular data-action associated

  $("#asd").change(function() {

    readImage(this);
    alert('Test');

  });


});

谢谢!