मैं एमईआरएन स्टैक का उपयोग कर रहा हूं और मैं इसे बाद में स्टोर करने के लिए फ्रंट एंड (प्रतिक्रिया) में एक छवि अपलोड करने और बैकएंड (एक्सप्रेस, नोडज) में एक्सेस करने में सक्षम होना चाहता हूं। मैं मल्टर का उपयोग कर रहा हूं लेकिन जब मैं console.log() req.file ऑब्जेक्ट का प्रयास करता हूं तो मैं अपरिभाषित हो जाता हूं।

फ़्रंट एंड:

import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { addPlayer } from "../../actions/profileActions";

class AddPlayer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      avatarFile: null,
      name: "",
      age: "",
      apodo: "",
      captain: false,
      description: "",
      atributes: "",
      facebook: "",
      instagram: "",
      twitter: "",
      youtube: "",
    };
    this.onSubmit = this.onSubmit.bind(this);
    this.onImageChange = this.onImageChange.bind(this);
  }

  onSubmit(e) {
    e.preventDefault();

    const playerData = {
      name: this.state.name,
      age: this.state.age,
      apodo: this.state.apodo,
      captain: this.state.captain,
      description: this.state.description,
      atributes: this.state.atributes,
      facebook: this.state.facebook,
      instagram: this.state.instagram,
      twitter: this.state.twitter,
      youtube: this.state.youtube
    };

    this.props.addPlayer(playerData, this.props.history);
  }

  onImageChange(event) {
    if (event.target.files && event.target.files[0]) {
      this.setState({ avatarFile: event.target.files[0] });
    }
  }

  render() {
    return(
      <div>
        <form
          onSubmit={this.onSubmit}
          method="POST"
          encType="multipart/form-data"
        >
          <div className="text-center mb-3">
            <input
              type="file"
              name="file"
              id="file"
              accept="image/*"
              className="inputfile"
              onChange={this.onImageChange}
             />
             <label htmlFor="file" className="btn btn-primary">
               Elegir foto
             </label>
            </div>
        </form>
      </div>
    );
  }

}

AddPlayer.propTypes = {
  addPlayer: PropTypes.func.isRequired,
  profile: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { addPlayer }
)(withRouter(AddPlayer));

जोड़ें प्लेयर कार्रवाई

//Create player
export const addPlayer = (playerData, history) => dispatch => {
  axios
    .post("api/profile/player", playerData)
    .then(res => history.push("/dashboard"))
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

यह सिर्फ प्लेयर डेटा पोस्ट करता है और फिर किसी अन्य घटक पर रीडायरेक्ट करता है।

बैकएंड दो फाइलों में बांटा गया है। server.js जहां सभी मिडलवेयर सेट किए गए हैं और profile.js जिसमें सभी मार्ग शामिल हैं।

बैकएंड server.js

const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const cors = require("cors");

const users = require("./routes/api/users");
const profile = require("./routes/api/profile");
const matches = require("./routes/api/matches");

const app = express();

//body-parser middleware
app.use(bodyParser.urlencoded({ extended: false, limit: "50mb" }));
app.use(bodyParser.json({ limit: "50mb" }));

//db config
const db = require("./config/keys").mongoURI;

//cors
app.use(cors());

//connect to mongoose
mongoose
  .connect(
    db,
    { useNewUrlParser: true }
  )
  .then(() => console.log("MongoDB connected"))
  .catch(err => console.log(err));

//Passport middleware
app.use(passport.initialize());

//Passport config
require("./config/passport")(passport);

app.use("/api/profile", profile);

const port = process.env.PORT || 5000;

app.listen(port, () => console.log(`server running on port ${port}`));

profile.js

const express = require("express");
const router = express.Router();
const passport = require("passport");
const multer = require("multer");

const parser = multer({ dest: "./images" });

router.post(
  "/player",
  [passport.authenticate("jwt", { session: false }), parser.single("file")],
  (req, res) => {

const newPlayer = {
  name: req.body.name,
  age: req.body.age,
  apodo: req.body.apodo,
  description: req.body.description,
  captain: req.body.captain,
  social: {
    instagram: req.body.instagram,
    facebook: req.body.facebook,
    twitter: req.body.twitter,
    youtube: req.body.youtube
  }
};
//set the Avatar for the player
console.log(req.file);
});

किसी भी सहायता के लिए धन्यवाद। धन्यवाद।

1
facundo rotger 27 पद 2018, 04:19

1 उत्तर

सबसे बढ़िया उत्तर

ऐसा लगता है कि आपको दो समस्याएं हैं:

  1. आप सही सामग्री प्रकार का उपयोग नहीं कर रहे हैं (axios डिफ़ॉल्ट रूप से application/json मानेंगे और आपको multipart/form-data की आवश्यकता होगी)
  2. आप मान रहे हैं कि अपलोड केवल काम करेगा क्योंकि यह एक फॉर्म का हिस्सा है, जब आप onSubmit को ओवरराइड करते हैं और e.preventDefault() को कॉल करते हैं तो आप उस फॉर्म के लिए किसी भी डिफ़ॉल्ट ब्राउज़र व्यवहार को रद्द कर देते हैं और फ़ाइल को मैन्युअल रूप से प्राप्त करने की आवश्यकता होती है सर्वर (मुझे आपके वर्तमान कोड में ऐसा कुछ भी नहीं दिख रहा है)।

इसे काम करने के लिए कुछ बदलावों की आवश्यकता है, पहला कदम फ़ाइल जानकारी को अपनी कार्रवाई में पास करना है। ऐसा करने का सबसे आसान तरीका है कि आप अपने file फ़ील्ड में एक रेफरी जोड़ें

<input ref={c => this.img = c} ...

फिर onSubmit फ़ंक्शन में, आप इस रेफरी का उपयोग फ़ाइल DOM से ऑब्जेक्ट को एक्शन पेलोड में भेजने के लिए

onSubmit(e) {
  e.preventDefault();

  const playerData = {
    ...this.state,
    file: this.img.files[0]
  }

  this.props.addPlayer(playerData, this.props.history);
}

कार्रवाई में, आपको multipart/form-data अनुरोध के रूप में डेटा भेजने की आवश्यकता है, ऐसा करने के लिए आप बस FormData से axios पर जाएं और इसे उपयुक्त हेडर आदि सेट करने दें।

export const addPlayer = (playerData, history) => dispatch => {
  // build form data
  const form = Object.keys(playerData).reduce((f, k) => {
    f.append(k, playerData[k]);
    return f;
  }, new FormData());
  // send request
  return axios
    .post("api/profile/player", form)
    .then(res => history.push("/dashboard"))
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

आपका सर्वर कोड चाहिए वैसे ही काम करना चाहिए जैसा है।

1
James 28 पद 2018, 03:11