Как загрузить файл в базу данных MySQL с помощью серверной части Nodejs и отобразить фотографию

#javascript #html #node.js #reactjs #multer

Вопрос:

Я пытаюсь загрузить фотографию в базу данных MySQL, используя серверную часть узла, но по какой-то причине я понимаю, что то, что я загрузил, не определено.

Я объявил новую переменную «Photo2», в которой хранится эта фотография, и я консолирую.войдите в систему, но я получаю «неопределенный» в своей консоли

Форма:

 import axios from "axios"; import { React, useState, useEffect } from "react"; import { useHistory, withRouter } from "react-router-dom";  function UserMaster_Edit(props) {  const [CmpnyCode, setCmpnyCode] = useState("");  const [UserID, setUserID] = useState("");  const [UserFullName, setUserFullName] = useState("");  const [UserDetail, setUserDetail] = useState("");  const [LoginID, setLoginID] = useState("");  const [Password, setPassword] = useState("");  const [UserPin, setUserPin] = useState("");  const [UserEmailID, setUserEmailID] = useState("");  const [UserFP, setUserFP] = useState("");  const [Photo, setPhoto] = useState("");  const [IsActive, setIsActive] = useState("");  const [LicCount, setLicCount] = useState("");  const [DateCreated, setDateCreated] = useState("");  const [CreatedBy, setCreatedBy] = useState("");  const [RecordChanged, setRecordChanged] = useState("");  const [LocationID, setLocationID] = useState("");  const [isValid, setisValid] = useState("");  const [isDeleted, setisDeleted] = useState("");   const history = useHistory();   const argu = props.match.params.UserID;   useEffect(() => {  axios.get("http://localhost:8000/getuserid/"   argu).then((response) => {  setCmpnyCode(response.data[0].CmpnyCode);  setUserID(response.data[0].UserID);  setUserFullName(response.data[0].UserFullName);  setUserDetail(response.data[0].UserDetail);  setLoginID(response.data[0].LoginID);  setPassword(response.data[0].Password);  setUserPin(response.data[0].UserPin);  setUserEmailID(response.data[0].UserEmailID);  setUserFP(response.data[0].UserFP);  setPhoto(response.data[0].Photo);  setIsActive(response.data[0].IsActive.data[0]);  setLicCount(response.data[0].LicCount);  setDateCreated(response.data[0].DateCreated);  setCreatedBy(response.data[0].CreatedBy);  setRecordChanged(response.data[0].RecordChanged.data[0]);  setLocationID(response.data[0].LocationID);  setisValid(response.data[0].isValid);  setisDeleted(response.data[0].isDeleted);  });  }, [argu]);   const editData = () => {  axios.put("http://localhost:8000/upusermst/"   argu, {  CmpnyCode,  UserID,  UserFullName,  UserDetail,  LoginID,  Password,  UserPin,  UserEmailID,  UserFP,  Photo,  IsActive,  LicCount,  DateCreated,  CreatedBy,  RecordChanged,  LocationID,  isValid,  isDeleted,  });  history.push("/usermst");  };   return (  <div className="App">  <div className="auth-wrapper">  <div className="auth-inner">  <form enctype="multipart/form-data" onSubmit={() => editData()}>  <h3> Edit User Master</h3>  <div>  <div className="form-class8">  <div className="form-group">  <label>Company Code</label>  <input  type="text"  className="form-control"  placeholder="CompanyCode"  value={CmpnyCode}  onChange={(e) => {  setCmpnyCode(e.target.value);  }}  name="CmpnyCode"  />  </div>   <div className="form-group">  <label>UserID</label>  <input  type="text"  className="form-control"  placeholder="UserID"  value={UserID}  onChange={(e) => {  setUserID(e.target.value);  }}  name="UserID"  />  </div>   <div className="form-group">  <label>UserFullName</label>  <input  type="text"  className="form-control"  placeholder="UserFullName"  value={UserFullName}  onChange={(e) => {  setUserFullName(e.target.value);  }}  name="UserFullName"  />  </div>   <div className="form-group">  <label>UserDetail</label>  <input  type="text"  className="form-control"  placeholder="UserDetail"  onChange={(e) => {  setUserDetail(e.target.value);  }}  name="UserDetail"  value={UserDetail}  />  </div>   <div className="form-group">  <label>LoginID</label>  <input  type="text"  className="form-control"  placeholder="LoginID"  onChange={(e) => {  setLoginID(e.target.value);  }}  name="LoginID"  value={LoginID}  />  </div>   <div className="form-group">  <label>Password</label>  <input  type="text"  className="form-control"  placeholder="Password"  onChange={(e) => {  setPassword(e.target.value);  }}  name="Password"  value={Password}  />  </div>   <div className="form-group">  <label>UserPin</label>  <input  type="text"  className="form-control"  placeholder="UserPin"  onChange={(e) => {  setUserPin(e.target.value);  }}  name="UserPin"  value={UserPin}  />  </div>   <div className="form-group">  <label>UserEmailID</label>  <input  type="email"  className="form-control"  placeholder="UserEmailID"  onChange={(e) => {  setUserEmailID(e.target.value);  }}  name="UserEmailID"  value={UserEmailID}  />  </div>  </div>   <div className="form-class8">  <div className="form-group">  <label>UserFP</label>  <input  type="file"  className="form-control"  placeholder="UserFP"  onChange={(e) => {  setUserFP(e.target.value);  }}  name="UserFP"  value={UserFP}  />  </div>   <div className="form-group">  <label>Photo</label>  <input  type="file"  className="form-control"  placeholder="Photo"  onChange={(e) => {  setPhoto(e.target.value);  }}  name="Photo"  value={Photo}  />  </div>   <div className="form-group">  <label>IsActive</label>  <input  type="text"  className="form-control"  placeholder="IsActive"  onChange={(e) => {  setIsActive(e.target.value);  }}  name="IsActive"  value={IsActive}  />  </div>   <div className="form-group">  <label>LicCount</label>  <input  type="text"  className="form-control"  placeholder="LicCount"  onChange={(e) => {  setLicCount(e.target.value);  }}  name="LicCount"  value={LicCount}  />  </div>   <div className="form-group">  <label>DateCreated</label>  <input  type="text"  className="form-control"  placeholder="DateCreated"  onChange={(e) => {  setDateCreated(e.target.value);  }}  name="DateCreated"  value={DateCreated}  />  </div>   <div className="form-group">  <label>CreatedBy</label>  <input  type="text"  className="form-control"  placeholder="CreatedBy"  onChange={(e) => {  setCreatedBy(e.target.value);  }}  name="CreatedBy"  value={CreatedBy}  />  </div>   <div className="form-group">  <label>RecordChanged</label>  <input  type="text"  className="form-control"  placeholder="RecordChanged"  onChange={(e) => {  setRecordChanged(e.target.value);  }}  name="RecordChanged"  value={RecordChanged}  />  </div>   <div className="form-group">  <label>LocationID</label>  <input  type="text"  className="form-control"  placeholder="LocationID"  onChange={(e) => {  setLocationID(e.target.value);  }}  name="LocationID"  value={LocationID}  />  </div>  </div>   <div className="form-class8">  <div className="form-group">  <label>isValid</label>  <input  type="date"  className="form-control"  placeholder="isValid"  onChange={(e) => {  setisValid(e.target.value);  }}  name="isValid"  value={isValid}  />  </div>   <div className="form-group">  <label>isDeleted</label>  <input  type="date"  className="form-control"  placeholder="isDeleted"  onChange={(e) => {  setisDeleted(e.target.value);  }}  name="isDeleted"  value={isDeleted}  />  </div>  </div>   <button className="btn btn-primary btn-block">Edit</button>  </div>  </form>  </div>  </div>  </div>  ); }  export default withRouter(UserMaster_Edit);  

Поля, которые вы ищете, — это UserFP и Фотография, которые имеют тип файла.

Серверная часть узла:

 const multer = require("multer"); const upload = multer({ storage: multer.memoryStorage() });   app.put("/upusermst/:UserID", upload.single("Photo"), (req, res) => {  const userid = req.params.UserID;  const CompanyCode = req.body.CmpnyCode;  const UserID = req.body.UserID;  const UserFullName = req.body.UserFullName;  const UserDetail = req.body.UserDetail;  const LoginID = req.body.LoginID;  const Password = req.body.Password;  const UserPin = req.body.UserPin;  const UserEmailID = req.body.UserEmailID;  const UserFP = req.body.UserFP;  const Photo = req.body.Photo;  const Photo2 = req.file;  const IsActive = req.body.IsActive;  const LicCount = req.body.LicCount;  const DateCreated = req.body.DateCreated;  const CreatedBy = req.body.CreatedBy;  const RecordChanged = req.body.RecordChanged;  const LocationID = req.body.LocationID;  const isValid = req.body.isValid;  const isDeleted = req.body.isDeleted;  console.log(Photo2);  db.query(  "UPDATE usermst SET CmpnyCode=?,UserID=?,UserFullName=?,UserDetail=?,LoginID=?,Password=?,UserPin=?,UserEmailID=?,UserFP=?,Photo=?,IsActive=?,LicCount=?,DateCreated=?,CreatedBy=?,RecordChanged=?,LocationID=?,isValid=?,isDeleted=? WHERE UserID=?",  [  CompanyCode,  UserID,  UserFullName,  UserDetail,  LoginID,  Password,  UserPin,  UserEmailID,  UserFP,  Photo,  IsActive,  LicCount,  DateCreated,  CreatedBy,  RecordChanged,  LocationID,  isValid,  isDeleted,  userid,  ],  (err, result) => {  if (err) {  console.log(err);  } else {  res.send(result);  }  }  ); });  

Обратите внимание, что уже есть переменная с именем Photo, но это было то, что я делал раньше, теперь я делаю req.файл для Фото2, и это приводит к тому, что значение не определено.

Я был бы очень признателен, если бы кто-нибудь мог отредактировать код для меня для лучшего понимания с некоторым объяснением того, почему я могу получить неопределенное значение для «Photo2».

Ответ №1:

После долгих поисков я, наконец, понял проблему. Я не устанавливал jQuery, поэтому put отправляемый запрос axios давал результат, не определенный в бэкэнде. Я использовал fetch вместо этого, и это сработало. Код теперь выглядит следующим образом: Форма:

 const uploadPhoto = (event, argu) => {  event.preventDefault();  const formData = new FormData();  formData.append("avatar", Photo);  fetch("http://localhost:8000/uploadphoto/"   argu, {  method: "PUT",  body: formData,  });  };   <form enctype="multipart/form-data">  <div className="form-group">  <label>Photo</label>  <input  type="file"  className="form-control"  placeholder="Photo"  onChange={(e) => {  setPhoto(e.target.files[0]);  }}  id="Photo"  name="Photo"  /> </form>  

Бэкэнд:

 const multer = require("multer"); const fs = require("fs");  const upload = multer({ dest: "uploads/" });   app.put("/uploadphoto/:UserId", upload.single("avatar"), (req, res) => {  const userid = req.params.userId;  const photo = req.file;  const fileType = photo.mimetype.split("/")[1];  let newFileName = photo.filename   "."   fileType;   fs.rename(  `./uploads/${photo.filename}`,  `./uploads/${newFileName}`,  function () {  console.log("file renamed and uploaded");  }  );  console.log(photo);  console.log("fileName ", newFileName);   db.query(  "UPDATE usermst SET Photo=? WHERE UserID=?",  [newFileName, userid],  (err, result) => {  console.log(err);  res.json({ result });  }  ); });```   

Ответ №2:

Потому что входные данные типа файла отсутствуют e.target.value . Те находятся внутри e.target.files . Так как у вас есть только одно изображение, которое было бы e.target.files[0] в вашем случае.

 <input  type="file"  lassName="form-control"  placeholder="Photo"  onChange={(e) => {  setPhoto(e.target.files[0]);  }}  name="Photo" />  

Кстати, вы не можете просто отправить файл вместе с запросом. Вам нужно использовать formData вместо этого.

Посмотрите мой минимальный пример:

 import { useState } from "react";  export default function PrivatePage(props) {  const [image, setImage] = useState(null);  const [createObjectURL, setCreateObjectURL] = useState(null);   const uploadToClient = (event) => {  if (event.target.files amp;amp; event.target.files[0]) {  const i = event.target.files[0];   setImage(i);  setCreateObjectURL(URL.createObjectURL(i));  }  };   const uploadToServer = async (event) => {  const body = new FormData();  body.append("file", image);  const response = await fetch("/api/formidable", {  method: "POST",  body  });  };   return (  <div>  <div>  {createObjectURLamp;amp;<img height="500px" width="1000px" src={createObjectURL}/>}  <h4>Select Image</h4>  <input type="file" name="myImage" onChange={uploadToClient} />  <button  className="btn btn-primary"  type="submit"  onClick={uploadToServer}  >  Send to server  </button>  </div>  </div>  ); }  

Комментарии:

1. Я сделал это, и теперь я получаю следующую ошибку в своей консоли: react-dom.development.js:1383 Неперехваченное исключение DOMException: Не удалось установить свойство «значение» в «HTMLInputElement»: Этот элемент ввода принимает имя файла, которое может быть задано только программно в виде пустой строки. в HTMLInputElement.установите [в качестве значения] И весь интерфакт просто гаснет, я вижу только фон

2. Нет, я использую экспресс

3. Я удалил value ={photo} , но я все еще не определился в своей внутренней консоли

4. Это не решило проблему. Все та же ошибка, о которой я упоминал в приведенном выше комментарии, Ошибка возникает при <вводе/>, Как только я выбираю изображение, ошибка появляется в консоли, и интерфейс становится пустым

5. Да, пожалуйста, это было бы здорово