因此,我是MERN Stack的新手,并设置了一个表格来上传图像并将其发送到AWS s3中的存储桶。我没有回应。我确定我的代码中肯定有一些错误。我没有回应。我已经按照教程进行操作,但是我的代码无法正常工作。 Server.js
const express = require("express");
const aws = require("aws-sdk");
var cors = require("cors");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const app = express();
const items = require("./routes/api/items"); // Contains all the api routes
// for uploading the images
const fs = require("fs");
const fileType = require("file-type");
const bluebird = require("bluebird");
const multiparty = require("multiparty");
// Body Parser middleware
app.use(bodyParser.json());
app.use(cors());
// DB config
const db = require("./config/keys").mongoURI;
// config for access key and id
aws.config.update({
region: "us-east-1",
accessKeyId: process.env.AWSAccessKeyId,
secretAccessKey: process.env.AWSSecretKey
});
const S3_BUCKET = process.env.bucket;
console.log(S3_BUCKET);
exports.sign_s3 = (req, res) => {
const s3 = new aws.S3(); // Create a new instance of S3
const fileName = req.body.fileName;
const fileType = req.body.fileType;
// Set up the payload of what we are sending to the S3 api
const s3Params = {
Bucket: S3_BUCKET,
Key: fileName,
Expires: 500,
ContentType: fileType,
ACL: "public-read"
};
// Make a request to the S3 API to get a signed URL which we can use to upload our file
s3.getSignedUrl("putObject", s3Params, (err, data) => {
if (err) {
console.log(err);
res.json({ success: false, error: err });
}
// Data payload of what we are sending back, the url of the signedRequest and a URL where we can access the content after its saved.
const returnData = {
signedRequest: data,
url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`
};
// Send it all back
res.json({ success: true, data: { returnData } });
});
};
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log("Mongo is laoded"))
.catch(err => console.log(err));
app.use("/api/items", items); // redirecting api routes to items
const port = process.env.PORT || 5000;
app.listen(port, () => console.log("Server started"));
我将AWS凭证存储在根目录下的.env文件中。我的表格的其他组件工作正常。仅图像未存储在aws中。 我将尝试抽象代码以删除不需要的细节。 UserForm.jsx
handleSubmit = e => {
e.preventDefault();
let file = this.uploadInput.files[0];
// Split the filename to get the name and type
let fileParts = this.uploadInput.files[0].name.split(".");
let fileName = fileParts[0];
let fileType = fileParts[1];
console.log("Preparing the upload");
axios
.post("http://localhost:5000/api/items", {
fileName: fileName,
fileType: fileType
})
.then(response => {
var returnData = response.data.data.returnData;
var signedRequest = returnData.signedRequest;
var url = returnData.url;
this.setState({ url: url });
console.log("Recieved a signed request " + signedRequest);
// Put the fileType in the headers for the upload
var options = {
headers: {
"Content-Type": fileType
}
};
axios
.put(signedRequest, file, options)
.then(result => {
console.log("Response from s3");
this.setState({ success: true });
})
.catch(error => {
alert("ERROR " + JSON.stringify(error));
});
})
.catch(error => {
alert(JSON.stringify(error));
});
// update ends
const users = {
name: this.state.name,
contact: this.state.contact,
company: this.state.company,
mail: this.state.mail,
key: this.state.key,
apps_no: this.state.apps_no
};
axios
.post(
"http://localhost:5000/api/items",
{
name: users.name,
contact_no: users.contact,
company_name: users.company,
key: users.key,
mail: users.mail,
apps_no: users.apps_no
},
{
headers: {
"content-type": "application/json"
}
}
)
.then(res => {
console.log("Post submitted with response " + res.status);
console.log("Mail: " + users.mail);
})
.catch(function(error) {
console.log(error);
});
this.props.history.push("/form-submitted");
};
componentDidMount() {
axios.get("http://localhost:5000/api/items").then(resp => {
console.log(resp.data);
});
}
在渲染功能中,我正在表单标签中使用onClick标记来提交详细信息。输入栏位: << / p>
center>
<h1>UPLOAD A FILE</h1>
{this.state.success ? <Success_message /> : null}
<input
onChange={this.handleFileChange.bind(this)}
ref={ref => {
this.uploadInput = ref;
}}
type="file"
/>
<br />
控制台:
Array(22)
UserForm.jsx:54 Preparing the upload
UserForm.jsx:115 Post submitted with response 200
我的代码显然有很多错误。帮助将不胜感激。 编辑: items.js-
const express = require("express");
const router = express.Router();
// Item model
const Item = require("../../models/Item");
// Routes
// @get API item get all items
// make a get req
router.get("/", (req, res) => {
Item.find().then(items => res.json(items));
});
// @get Api item POST all items
// make a post req
// create an item
router.post("/", (req, res) => {
const newItem = new Item({
name: req.body.name,
contact_no: req.body.contact_no,
company_name: req.body.company_name,
key: req.body.key,
mail: req.body.mail,
apps_no: req.body.apps_no
});
newItem.save().then(item => res.json(item));
});
// @del api item.
// delete request
router.delete("/:id", (req, res) => {
Item.findById(req.params.id)
.then(item => item.remove().then(() => res.json({ success: true })))
.catch(err => res.status(404).json({ success: false }));
});
module.exports = router;
答案 0 :(得分:0)
这就是我们要做的:
我们确实在环境中配置过AWS cli,请检查以下链接:https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html,实时运行您的项目以安全的方式配置和读取所需的AWS密钥,但不要将任何密钥存储在.env文件或脚本之后的代码如下:
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
let putParams = {
Body: fileCotent,
Bucket: s3BucketName,
Key: fileName,
ContentType:'image/png'
};
s3.putObject(putParams, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
done();
});
答案 1 :(得分:0)
您通过请求得到signedUrl
POST /api/items
axios
.post("http://localhost:5000/api/items", {
fileName: fileName,
fileType: fileType
})
但是,您的路由器处理POST /api/items
来保存Item
的请求(而不是获取S3signedUrl)。
在处理程序中,您仅处理成功案例newItem.save().then(item => res.json(item));
,然后在调用无效正文(fileName
,fileType
)的请求时,该请求绝不会在错误情况下响应(此表示您的客户仍然“永远等待”)
解决方案:创建一个新路由器,它将处理获取签名的URL请求
更新您的客户端Server.js
app.post('/signed-url', exports.sign_s3); // this line
mongoose
...
更新客户端UserForm.jsx
:
console.log("Preparing the upload");
axios
.post("http://localhost:5000/signed-url") // instead of http://localhost:5000/api/items