AWS S3-由于包含错误,无法显示图像

问题描述 投票:0回答:2

我目前正在使用React,Redux,JavaScript,Node,Adonisjs构建注册表单。我正在尝试将个人资料图像上传到我的AWS s3存储桶。目前,我已经知道了,因此文件出现在存储桶中。但是,当我尝试单击AWS s3提供的链接时,出现以下错误。 AWS ERROR IMAGE

我已将我的权限设置为公开,并且我提供了正确的凭据密钥。我坚持如何解决此问题,因此将不胜感激任何帮助。请参见下面的代码。

下面是我的AWS控制器:

"use strict";

require("dotenv").config();
const aws = require("aws-sdk");
const fs = require("fs");
const Helpers = use("Helpers");
const Drive = use("Drive");

class awsController {
  async upload({ request, response }) {
    aws.config.update({
      region: "ap-southeast-2", // AWS region
      accessKeyId: process.env.S3_KEY,
      secretAccessKey: process.env.S3_SECERT
    });

    const S3_BUCKET = process.env.S3_BUCKET;

    const s3Bucket = new aws.S3({
      region: "ap-southeast-2",
      accessKeyId: process.env.S3_KEY,
      secretAccessKey: process.env.S3_SECERT,
      Bucket: process.env.S3_BUCKET
    }); // Create a new instance of S3

    const fileName = request.all().body.fileName;
    console.log(fileName);
    const fileType = request.all().body.fileType;

    const params = {
      Bucket: S3_BUCKET,
      Key: fileName,
      ContentType: fileType,
      ACL: "public-read"
    };

    s3Bucket.putObject(params, function(err, data) {
      if (err) {
        response.send(err);
      }
      console.log(data);

      const returnData = {
        signedRequest: data,
        url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`
      };

      console.log(returnData);
      response.send("Success");
    });
  }
}

module.exports = awsController;

**下面处理文件的上传**


import React, { Component } from "react";
import axiosAPI from "./../resorterAPI";
import axios from "axios";

class ImageUpload extends Component {
  constructor(props) {
    super(props);
    this.state = {
      success: false,
      url: ""
    };
  }

  handleChange = event => {};

  handleUpload = event => {
    let uploadedFile = this.uploadInput.files[0];

    // Splits name of file
    let fileParts = this.uploadInput.files[0].name.split(".");
    let fileName = fileParts[0];
    let fileType = fileParts[1];
    let fullFileName = uploadedFile.name;

    console.log("preparing upload");

    axiosAPI
      .post("/s3Upload", {
        body: {
          fileName:
            Math.round(Math.random() * 1000 * 300000).toString() +
            "_" +
            uploadedFile.name,
          fileType: fileType
        }
      })
      .then(response => {
        console.log("Success");
      });
  };

  render() {
    return (
      <div>
        <center>
          <input
            onChange={this.handleChange}
            ref={ref => {
              this.uploadInput = ref;
            }}
            type="file"
          />
          <br />
          <button onClick={this.handleUpload}> Upload </button>
        </center>
      </div>
    );
  }
}

export default ImageUpload;

**下面是图像上传服务的名称,**

import React from "react";

// Redux
import { Field, reduxForm } from "redux-form";
import { connect } from "react-redux";
import { getCountry } from "./../../redux/actions/getCountryAction.js";
import Store from "./../../redux/store.js";

// Services
import axiosAPI from "./../../api/resorterAPI";
import ImageUpload from "./../../api/services/ImageUpload";

// Calls a js file with all area codes matched to countries.
import phoneCodes from "./../../materials/PhoneCodes.json";

// Component Input
import {
  renderField,
  renderSelectField,
  renderFileUploadField
} from "./../FormField/FormField.js";

// CSS
import styles from "./signupForm.module.css";
import classNames from "classnames";

function validate(values) {
  let errors = {};

  if (!values.specialisations) {
    errors.firstName = "Required";
  }

  if (!values.resort) {
    errors.lastName = "Required";
  }

  if (!values.yearsOfExperience) {
    errors.email = "Required";
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = "Invalid Email";
  }

  if (!values.spokenLanguages) {
    errors.password = "Required";
  }

  if (values.sport !== values.confirmPassword) {
    errors.confirmPassword = "Passwords don't match";
  }

  return errors;
}

class SignupFormStepTwo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      countries: [],
      selectedCountry: [],
      dialCodes: []
    };
  }

  // Below gets the countries from axios call made in redux actions
  async componentDidMount() {
    const countries = await getCountry();
    // The below maps through the json file and gets all the dial codes
    const codes = phoneCodes.phoneCode.map(code => {
      return code.dial_code;
    });
    return this.setState({ countries: countries, dialCodes: codes });
  }

  // Handles when someone changes the select fields
  handleChange = event => {
    const selectedCountry = event.target.value;
    return this.setState({ selectedCountry: selectedCountry });
  };

  // uploadFile = (values, url = "") => {
  //   axiosAPI.post("/displayImageUpload", { ...values, imageURL: url}).then(response => {
  //     console.log("Success");
  //   })
  // }

  render() {
    return (
      <div>
        <form onSubmit={this.props.handleSubmit}>
          <div className={styles.signupContainer}>
            <div className={styles.signupInputContainer}>
              {/* <Field
                name="displayImage"
                component={renderFileUploadField}
                type="text"
                label="Display Image"
              /> */}

              <ImageUpload />

              <div
                className={classNames({
                  [styles.bioField]: true,
                  [styles.signupInputContainer]: true
                })}
              >
                <Field
                  name="bio"
                  component={renderField}
                  type="text"
                  label="Bio"
                  placeholder="Introduce yourself - Where you're from, what your hobbies are, etc..."
                />
              </div>
            </div>

            {/* Renders the select field  */}
            <div className={styles.signupInputContainer}>
              <Field
                name="specialisations"
                component={renderSelectField}
                type="select"
                label="Specialisations"
                placeholder="Specialisations"
                options={this.state.countries}
                onChange={this.handleChange}
                multiple={false}
              />

              <Field
                name="resort"
                component={renderSelectField}
                options={this.state.dialCodes}
                type="select"
                label="Resort"
                placeholder="Select the resorts you can work at"
              />

              <Field
                name="yearsOfExperience"
                component={renderSelectField}
                options={this.state.dialCodes}
                type="select"
                label="Years of Experience"
              />

              <Field
                name="spokenLanguages"
                component={renderSelectField}
                options={this.state.dialCodes}
                type="select"
                label="Spoken Languages"
              />
            </div>
          </div>
          <div className={styles.signupButtonContainer}>
            <button className={styles.signupButton} type="submit">
              {" "}
              Submit{" "}
            </button>
          </div>
        </form>
      </div>
    );
  }
}

// destroyOnUnmount - saves it in state
SignupFormStepTwo = reduxForm({
  form: "signupStageTwo",
  destroyOnUnmount: false,
  validate
})(SignupFormStepTwo);

const mapStateToProps = state => {
  return {
    form: state.form
  };
};

export default SignupFormStepTwo;

node.js reactjs amazon-web-services amazon-s3 image-uploading
2个回答
0
投票

更新:感谢Jarmod解决了该错误,实际上我没有将文件扩展名与文件名分开,因此它正在上传image.png.png。但是,现在存在一个问题,其中上载的文件没有内容,并且是一个空文本文件。


0
投票

@@ jarmod-感谢您的回复。

这将我引向正确的方向。我到底需要在对象中放入什么?当我按如下所示放入完整文件对象时,它没有出现在s3存储桶中,但成功返回。然后,当我只输入fileName时,它会返回fileName的txt文件。任何帮助将不胜感激。

    // The below collects the data from the post including filename, type and the complete file object.
    const uploadedFile = request.all().body.file;
    const fileName = request.all().body.fileName;
    const fileType = request.all().body.fileType;
    console.log(fileType);
    console.log(fileName);

    // The below defines the params.
    const params = {
      Bucket: S3_BUCKET,
      Key: fileName,
      Body: file,
      ContentType: fileType,
      ACL: "public-read"
    };

    // The below sends the object off to AWS s3
    s3Bucket.putObject(params, function(err, data) {

      if (err) {
        response.send(err);
      }
      const returnData = {
        signedRequest: data,
        url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`
      };

      console.log("Success");
      response.send(returnData);
    });
  }
}

module.exports = awsController;
© www.soinside.com 2019 - 2024. All rights reserved.