#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. Да, пожалуйста, это было бы здорово