【问题标题】:AWS S3 - Image cannot be displayed because it contains errorsAWS S3 - 图像无法显示,因为它包含错误
【发布时间】:2020-06-17 14:16:39
【问题描述】:

我目前正在使用 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;

【问题讨论】:

  • 图像类型是否与文件扩展名和/或内容类型不匹配?您可以下载文件并验证其内容实际上是 JPEG。
  • 嘿@Jarmod,我将内容类型设置为当前上传的图像。那么不应该总是确保它匹配吗?如您所见,我正在通过 ContentType 传递文件类型。这能回答你的问题吗?
  • @jarmod - 你是对的,它正在上传带有扩展名的文件名,所以它正在上传 image.png.png。我已经解决了这个错误,但是现在文件没有内容,所以它出现在存储桶中,但它是一个空的文本文档。我将为这个问题创建一个新帖子。感谢您的帮助。

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


【解决方案1】:

更新:感谢 Jarmod 解决了错误,我实际上没有将文件扩展名与文件名分开,所以它正在上传 image.png.png。

【讨论】:

  • 您的putObject 电话没有正文。
猜你喜欢
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多