NodeJS Knox Formidable приводит к ошибке 400, файл не загружен в корзину S3

Я хочу использовать formidable и knox для загрузки файлов в корзину AWS S3, но каждый раз получаю 400, а файл не загружается. Мой код похож на этот: nodejs knox, помещенный в s3, приводит к 403, единственная разница в том, что первый аргумент моего readFile находится из моей временной папки Windows, я попробовал решение в комментарии, указав свое имя корзины это только маленькие буквы, но это тоже не сработало. Пожалуйста, помогите, если можете, спасибо. Мои коды ниже:

App.js

const express = require("express"),
  path = require("path"),
  config = require("./config"),
  knox = require("knox"),
  fs = require("fs"),
  os = require("os"),
  formidable = require("formidable"),
  gm = require("gm"),
  mongoose = require("mongoose");

mongoose.connect(config.dbURL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const app = express();

app.set("views", path.join(__dirname, "views"));
app.engine("html", require("hogan-express"));
app.set("view engine", "html");

app.use(express.static(path.join(__dirname, "public")));
app.set("port", process.env.PORT || 3000);
app.set("host", config.host);

let knoxClient = knox.createClient({
  key: config.S3AccessKey,
  secret: config.S3Secret,
  bucket: config.S3Bucket,
});

const server = require("http").createServer(app);
const io = require("socket.io")(server);

require("./routers")(
  express,
  app,
  formidable,
  fs,
  os,
  gm,
  knoxClient,
  mongoose,
  io
);

server.listen(app.get("port"), function () {
  console.info("PhotoGRID Running on port: " + app.get("port"));
});

Маршрутизатор (index.js)

module.exports = (
  express,
  app,
  formidable,
  fs,
  os,
  gm,
  knoxClient,
  mongoose,
  io
) => {
  //os.tmpDir = os.tmpdir;
  let Socket;

  io.on("connection", function (socket) {
    Socket = socket;
  });

  const singleImage = new mongoose.Schema({
    filename: {
      type: String,
      require: true,
    },
    votes: {
      type: Number,
      require: true,
    },
  });

  let singleImageModel = mongoose.model("singleImage", singleImage);
  let router = express.Router();

  router.get("/", function (req, res, next) {
    res.render("index", { host: app.get("host") });
  });

  router.post("/upload", function (req, res, next) {
    // File upload

    function generateFilename(filename) {
      let ext_regex = /(?:\.([^.]+))?$/;
      let ext = ext_regex.exec(filename)[1];
      let date = new Date().getTime();
      let charBank = "abcdefghijklmnopqrstuvwxyz";
      let fstring = "";
      for (let i = 0; i < 15; i++) {
        fstring += charBank[parseInt(Math.random() * 26)];
      }
      return (fstring += date + "." + ext);
    }

    let tmpFile, nFile, fName;
    let newForm = new formidable.IncomingForm();
    newForm.keepExtensions = true;
    newForm.parse(req, function (err, fields, files) {
      tmpFile = files.upload.path;
      fName = generateFilename(files.upload.name);
      nFile = os.tmpDir() + "/" + fName;
      res.writeHead(200, { "Content-type": "text/plain" });
      res.end();
    });

    newForm.on("end", function () {
      fs.rename(tmpFile, nFile, function () {
        // Resize the image and upload this file into the S3 bucket
        gm(nFile)
          .resize(300)
          .write(nFile, function () {
            // Upload to the S3 Bucket
            fs.readFile(nFile, function (err, buf) {
              let req = knoxClient.put(fName, {
                "Content-Length": buf.length,
                "Content-Type": "image/jpg",
              });

              req.on("response", function (res) {
                if (res.statusCode == 200) {
                  //This means that the file is in the S3 Bucket
                  console.info(fName + " is in the S3 bucket");

                  let newImage = new singleImageModel({
                    filename: fName,
                    votes: 0,
                  }).save();

                  Socket.emit("status", { msg: "Saved!!", delay: 3000 });
                  Socket.emit("doUpdate", {});

                  // Delete the Local file
                  fs.unlink(nFile, function () {
                    console.info("Local file deleted!");
                  });
                } else {
                  console.info(
                    err +
                      fName +
                      " did not get to the database or S3 bucket so " +
                      nFile +
                      " was not deleted " +
                      res.statusCode
                  );
                }
              });

              req.end(buf);
            });
          });
      });
    });
  });

  app.use("/", router);
};

index.html

<!DOCTYPE html>
<html lang = "en">
  <head>
    <meta charset = "UTF-8" />
    <title>PhotoGrid</title>
    <link rel = "stylesheet" href = "../css/main.css" />
    <script src = "http://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src = "/socket.io/socket.io.js"></script>
    <script src = "../js/photogrid_utils.js"></script>
    <script>
      $(function () {
        let host = "{{host}}";

        $(document).on("click", "#doUpload", function () {
          uploadNow();
        });

        let socket = io(host);

        socket.on("status", function (data) {
          showStatus(data.msg, data.delay);
        });

        socket.on("doUpdate", function () {
          renderList();
        });

        function uploadNow() {
          let uploadURL = host + "/upload";
          let uploadFile = $(".uploadPic");
          if (uploadFile.val() != "") {
            let form = new FormData();
            form.append("upload", uploadFile[0].files[0]);
            // Perform the AJAX POST request and send the file
            ajax({
              method: "post",
              url: uploadURL,
              success: function () {
                $(".progress").fadeOut(200);
                uploadFile.val("");
              },
              progress: function (e) {
                if (e.lengthComputable) {
                  let perc = Math.round((e.loaded * 100) / e.total);
                  $(".progress").css("width", perc + "%");
                }
              },
              payload: form,
            });
          }
        }
      });
    </script>
  </head>
  <body>
    <div class = "container">
      <div class = "topDeck">
        <div class = "logo">
          <a href = "{{host}}">
            <h1>PhotoGRID</h1>
          </a>
        </div>
        <div class = "controls">
          <input type = "file" name = "uploadPic" class = "uploadPic" />
          <button id = "doUpload">Upload</button>
          <div class = "progressBarDiv">
            <div class = "progress"></div>
          </div>
          <h5 class = "status"></h5>
        </div>
      </div>
      <div class = "gallery">
        <ul>
          <!-- Repeat the following <li> structure for every image -->
          <li>
            <div class = "overlay">
              <div class = "voteCtrl">
                <a href = "#" class = "voteUp">
                  <img
                    src = "../images/voteup.png"
                    alt = "Click Here to Vote Up !"
                  />
                  <h4>100</h4>
                </a>
              </div>
            </div>
            <div class = "imageHolder">
              <img src = "../images/someimage.jpg" alt = "" />
            </div>
          </li>
          <!-- End Repeat -->
        </ul>
      </div>
    </div>
  </body>
</html>

Согласуйте текущую реализацию/сценарий с возможными причинами, перечисленными здесь: aws.amazon.com/premiumsupport/knowledge-center/…

Alex 09.12.2020 23:42

@xandercoded Я рассмотрел все возможные причины и не думаю, что моя проблема вызвана какой-либо из них. Можете ли вы назвать какую-либо другую причину, по которой мои файлы не загружаются?

Zia 09.12.2020 23:53

Может выйти из строя по разным причинам. Какое ответное сообщение? Сравните код ответа 400 (или 403) с тем, что указано здесь docs.aws.amazon.com/AmazonS3/latest/API/….

Alex 10.12.2020 00:04

@xandercoded Я открыл ссылку и увидел так много кодов состояния 400 с их именами ошибок. То, что я пишу в консоль, это просто код состояния, я искренне не знаю, как написать имя ошибки в консоль. Если бы я только мог, это могло бы просто помочь мне узнать точную ошибку 400, с которой я имею дело.

Zia 10.12.2020 00:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не мог заставить свой код работать с knox, я продолжал получать статус-код 400, и мои файлы не загружались на S3. Поэтому я использовал aws-sdk, и это сработало как по волшебству. Мои файлы загружаются и сохраняются в моей базе данных монго. Для тех, кто может столкнуться с той же проблемой, вот что я сделал:

const { config } = require("aws-sdk");

module.exports = (express, app, formidable, fs, os, gm, s3, mongoose, io) => {
  //os.tmpDir = os.tmpdir;
  let Socket;

  io.on("connection", function (socket) {
    Socket = socket;
  });

  const singleImage = new mongoose.Schema({
    filename: {
      type: String,
      require: true,
    },
    votes: {
      type: Number,
      require: true,
    },
  });

  let singleImageModel = mongoose.model("singleImage", singleImage);
  let router = express.Router();

  router.get("/", function (req, res, next) {
    res.render("index", { host: app.get("host") });
  });

  router.post("/upload", function (req, res, next) {
    // File upload

    function generateFilename(filename) {
      let ext_regex = /(?:\.([^.]+))?$/;
      let ext = ext_regex.exec(filename)[1];
      let date = new Date().getTime();
      let charBank = "abcdefghijklmnopqrstuvwxyz";
      let fstring = "";
      for (let i = 0; i < 15; i++) {
        fstring += charBank[parseInt(Math.random() * 26)];
      }
      return (fstring += date + "." + ext);
    }

    let tmpFile, nFile, fName;
    let newForm = new formidable.IncomingForm();
    newForm.keepExtensions = true;
    newForm.parse(req, function (err, fields, files) {
      tmpFile = files.upload.path;
      fName = generateFilename(files.upload.name);
      nFile = os.tmpDir() + "\\" + fName;
      res.writeHead(200, { "Content-type": "image/JPG" });
      res.end();
    });

    newForm.on("end", function () {
      fs.rename(tmpFile, nFile, function () {
        // Resize the image and upload this file into the S3 bucket
        gm(nFile)
          .resize(300)
          .write(nFile, function () {
            // Upload to the S3 Bucket
            /* fs.readFile(nFile, function (err, buf) {
              let req = knoxClient.put(fName, {
                "Content-Length": buf.length,
                "Content-Type": "image/JPG",
                "x-amz-acl": "public-read",
              }); */

            const fileContent = fs.readFileSync(nFile);

            const params = {
              Bucket: require("../config").S3Bucket,
              Key: fName,
              Body: fileContent,
            };

            s3.upload(params, function (err, data) {
              // Delete the Local file
              fs.unlink(nFile, function (err) {
                console.info("Local file deleted!");
                if (err) {
                  console.error(err);
                }
              });
              console.info("PRINT FILE: ", fName);
              if (err) {
                console.info("ERROR MSG: ", err);
                res.status(500).send(err);
              } else {
                //This means that the file is in the S3 Bucket
                console.info(fName + " is in the S3 bucket");

                let newImage = new singleImageModel({
                  filename: fName,
                  votes: 0,
                }).save();

                Socket.emit("status", { msg: "Saved!!", delay: 3000 });
                Socket.emit("doUpdate", {});

                res.status(200).end();
              }
            });

            /*               req.on("response", function (res) {
                if (res.statusCode == 200) {
                  

                } else {
                  console.info(
                    err +
                      fName +
                      " did not get to the database or S3 bucket so " +
                      nFile +
                      " was not deleted " +
                      res.statusCode
                  );
                  console.info(res.statusMessage);
                }
              }); */

            // req.end(buf);
            //     });
          });
      });
    });
  });

  app.use("/", router);
};

Другие вопросы по теме