【问题标题】:Getting undefined filename, filetype when uploading files to AWS S3将文件上传到 AWS S3 时获取未定义的文件名、文件类型
【发布时间】:2019-02-18 17:16:18
【问题描述】:

我想做什么:
用AWS S3上传一个文件,然后把文件名和文件类型放在url的末尾保存到sql中,这样每次登录的时候都会通过用户图片url拉取图片。

问题:
不上传也不识别文件名或文件类型中的文件。在 URL 和 signedURL 中提出未定义的文件类型和文件名

我在 Node.js 中使用的 fileUploadService.js 的代码如下所示。

getSignedURL 看起来像这样:
https://sabio-training.s3.us-west-2.amazonaws.com/C56/filename/?AWSAccessKeyId=AKIAJF53EJKW7SJUV55Q&Content-Type=filetype&Expires=1536877443&Signature=WxSvLSzfyZKDRN9LawVOwj1ayVY%3D&x-amz-acl=public-read

网址如下所示:
https://sabio-training.s3.amazonaws.com/C56/filename/filetype

 const aws = require('aws-sdk');
aws.config.region = 'us-west-2';
aws.config.update({ accessKeyId: '', secretAccessKey: '' });
const PROFILE_S3_LINK = "https://sabio-training.s3.amazonaws.com/";

module.exports = {
  getUrl: getUrl
}

function getUrl(req, res) {
  
  const s3 = new aws.S3();
  const fileName = 'C56/'+"filename"+'/' ;  //hardcoded filename and filetype for it to work. 
  const fileType = "filetype";              //How to take filename from uploaded file to insert into "fileName" along with the "filetype"?
  const s3Params = {                        
    Bucket: 'sabio-training',                                                                       
    Key: fileName,                          
    Expires: 3000,
    ContentType: fileType,
    ACL: 'public-read'
  };

  s3.getSignedUrl('putObject', s3Params, (err, data) => {
    if (err) {
      console.log(err);
      return res.end();
    }
    const returnData = {
      signedRequest: data,
      url: `${PROFILE_S3_LINK}${fileName}${fileType}` //unsigned URL
    };
    res.write(JSON.stringify(returnData));
    res.end();
  });
}

=========================================================================
fileUploadRoute.js

const router = require("express").Router();
const fileUploadController = require("../controllers/fileUploadController")

router.put("/", fileUploadController.getUrl);

module.exports = router;

==========================================================================
fileUploadController.js

const fileUploadService = require('../services/fileUploadService')
const responses = require("../models/responses");

module.exports = {
    getUrl: getUrl
}

function getUrl(req, res) {
    fileUploadService.getUrl(req, res)
        .then(response => {
            res.send(response)
        })
        .catch(error => {
            res.send(error)
        })
}
===========================================================================
index.js in node portion


const router = require("express").Router();
const pogsRoutes = require("./pogs.routes");
const userFromJWT = require("../filters/jwt.user");
const validateUser = require("../filters/validate.user");
const testRoutes = require("./test.routes");
const profileRoute = require("../profile/profileRoute");
const fileUploadRoute = require("../fileUpload/fileUploadRoute")

module.exports = router;
// router.use("/api/profilePage", profileRoute)

router.use("/api/pogs", pogsRoutes);
router.use("/api/upload", fileUploadRoute)
router.use("/api/profilePage", profileRoute)
// -----------------------------------
// Authenticated routes go below this:
// -----------------------------------

router.use(userFromJWT);
router.use(validateUser);

router.use("/api/test", testRoutes); // TODO: remove this before delivery to the client

============================================================================
USED IN REACT

Axios pulled from profile page 

handleClickUpload = evt => {
        evt.preventDefault()
        console.log("RESULT : ", this.state);
        // var file = evt.target.files[0]; <-- havent used this yet but I know its for upload


        axios.put(`${NODE_API_URL}/api/upload`, {
                // f:file
        })
        .then(response =>{
                console.log(
                response,"URL SIGNED REQUEST : ",response.data.signedRequest, " URL : ",response.data.url
                )
        })
        .catch(error => {
                console.log(error);
        })
}

Upload button and file upload portion inside profile page

               <div method="post" encType="multipart/form-data" action="/">
        <input type="file" name="fileName" className="btn" />
        <input type="submit" value="Upload" className="btn" onClick={this.handleClickUpload}/>

谁能告诉我我做错了什么或者有什么遗漏?

【问题讨论】:

    标签: javascript node.js reactjs amazon-web-services amazon-s3


    【解决方案1】:

    首先,看看https://s3browser.com/features-content-mime-types-editor.aspx,你可以弄清楚你必须使用什么样的类型(对于ContentType)。我认为它应该是“text/plain”或“text/html”。 然后您必须向 s3 参数添加一个名为 Body 的属性(主体必须包含您要上传到 s3 存储桶的实体)

    这是一个 sn-p,您可以使用它来将您的实体上传到 s3,然后获取位置:

    let s3 = new AWS.S3({ region: process.env.AWS_REGION, apiVersion: '2006-03-01' });
    let params = 
    {
        Bucket:  // a bucket's location,
        Key: fileName // a path,
        Body:  // your entity to upload,
        ACL: 'public-read',
        ContentType: 'text/plain'
    };
    
    let s3Response = await s3.upload(params).promise();
    
          
    console.log(`Entity uploaded to S3 at ${s3Response.Bucket} bucket. Location: ${s3Response.Location}`);
    
    return s3Response.Location; 

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2012-05-12
      • 1970-01-01
      相关资源
      最近更新 更多