首页 > 解决方案 > 将图片发送到 aws s3 存储桶时出现 net::ERR_NAME_NOT_RESOLVED 错误

问题描述

我有一个使用 aws s3 存储图像的 Nodejs 应用程序。我使用 heroku 作为平台,并按照他们的程序从节点 js 连接到 aws。我可以从 aws 获取信息,但不能 PUT,即将图像上传到 aws s3。

这是我的 app.js

   var express = require("express"),
  bodyParser = require("body-parser"),
  mongoose = require("mongoose"),
  passport = require("passport"),
  LocalStrategy = require("passport-local"),
  flash = require("connect-flash"),
  compression = require("compression"),
  path = require("path"),
  aws = require("aws-sdk"),
  methodOverride = require("method-override");

aws.config.region = encodeURIComponent("EU (London)");
//aws.config.region = "";

var url = process.env.MONGODB_URI
  ? `${process.env.MONGODB_URI}/admin`
  : "mongodb://localhost/beirut";
//var url = "mongodb://localhost/beirut";
mongoose.connect(url, {
  useNewUrlParser: true,
  useFindAndModify: false,
  useCreateIndex: true,
  useUnifiedTopology: true,
  retryWrites: false,
});
const app = express();
app.use(
  require("express-session")({
    secret: "I fall in her trap , she was cute",
    resave: false,
    saveUninitialized: false,
  })
);
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(methodOverride("_method"));
app.use(flash());
app.use(function (req, res, next) {
  res.locals.currentUser = req.user; //defines user for all routes
  res.locals.error = req.flash("error"); // global variable to display flash messages
  res.locals.success = req.flash("sucess"); // global variable to display flash messages
  //  res.locals.dept ="test";
  next(); //middleware needs next to move onto next code
});
app.use(compression());
app.use(require("./routes/mainRoutes"));
app.use(require("./routes/userRoutes"));

app.set("view engine", "ejs");
app.set("views", "./views");

//app.use(express.static("public"));

const S3_BUCKET = process.env.S3_BUCKET;
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;

process.env.PWD = process.cwd();
app.use(express.static(path.join(process.env.PWD, "public")));
//app.use(express.static("public"));
//  aws routes

app.get("/sign-s3", (req, res) => {
  const s3 = new aws.S3({});
  const fileName = encodeURIComponent(req.query["file-name"]);
  const fileType = encodeURIComponent(req.query["file-type"]);
  const s3Params = {
    Bucket: S3_BUCKET,
    Key: fileName,
    Expires: 60,
    ContentType: fileType,
    ACL: "public-read-write",
  };
  console.log(s3Params);
  s3.getSignedUrl("putObject", s3Params, (err, data) => {
    if (err) {
      console.log(err);
      return res.end();
    }
    console.log(`DATA ${data}`);
    console.log(`FILENAME ${fileName}`);
    const returnData = {
      signedRequest: data,
      url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`,
    };

    res.write(JSON.stringify(returnData));
    res.end();
  });
});

// code to listen to request
var PORT = process.env.PORT || 3000;
var HOST = "0.0.0.0" || "127.0.0.1";
app.listen(PORT, HOST, function () {
  console.log("server started");
});

和上传图片表格

  <div class="container">
  <h3>Site:<%-site.Pname %></h3>
  <h3>Item:<%-page %></h3>
  <!-- <img id="preview" src="/uploads/default.jpg" /> -->

  <img
    id="preview"
    src="https://beirutblast1.s3.us-east-2.amazonaws.com/Fig+3.jpg"
    height="200px"
  />
  <form
    action="/upload/<%=item._id%>/<%=site._id%>"
    enctype="multipart/form-data"
    method="POST"
  >
    <input id="avatar-url" name="avatar-url" value="/uploads/default.jpg" />
    <input id="file-input" type="file" name="myImage" accept="image/*" />
    <input type="submit" value="Upload" />
  </form>
</div>

<script>
  (() => {
    document.getElementById("file-input").onchange = () => {
      const files = document.getElementById("file-input").files;
      const file = files[0];
      if (file == null) {
        return alert("No file selected.");
      }

      getSignedRequest(file);
    };
  })();

  function getSignedRequest(file) {
    const xhr = new XMLHttpRequest();

    xhr.open("GET", `/sign-s3?file-name=${file.name}&file-type=${file.type}`);
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          const response = JSON.parse(xhr.responseText);

          uploadFile(file, response.signedRequest, response.url);
        } else {
          alert("Could not get signed URL.");
        }
      }
    };
    xhr.send();
  }

  function uploadFile(file, signedRequest, url) {
    const xhr = new XMLHttpRequest();
    xhr.open("PUT", signedRequest);
    xhr.onreadystatechange = () => {
      // console.log(xhr);
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          document.getElementById("preview").src = url;
          document.getElementById("avatar-url").value = url;
        } else {
          alert("Could not upload file.");
        }
      }
    };
    xhr.send(file);
  }
</script>

请注意,我使用 .env 文件并使用 heroku local 运行我的应用程序

在此处输入图像描述

标签: amazon-web-servicesamazon-s3

解决方案


aws.config.region = encodeURIComponent("EU (London)")

在此处输入图像描述

“欧盟(伦敦)”不是有效的地区名称。伦敦的地区名称是“eu-west-2”。


推荐阅读