• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Node.js, Express 게시판 state에 저장한값을 multer를 통해 업로드 하려면?

state에 저장한값을 multer를 통해 업로드 하려면?

10 글 보임 - 1 에서 10 까지 (총 20 중에서)
  • 글쓴이
  • #69811

    강현우
    참가자
    <프론트>
    
    import 'bootstrap/dist/css/bootstrap.min.css'; //bootstrap
    import {Nav, Navbar, Container,Button,Form} from 'react-bootstrap';
    import {useNavigate} from 'react-router-dom';
    import {useState} from 'react'
    import axios from 'axios';
    function MakeLecture(){
    let navigate = useNavigate();
    let [info,setInfo] = useState({
    id: 0,
    title:'',
    teacher:'',
    detail:'',
    upload:''
     })
    const handleChange = (e)=>{
    setInfo({...info,[e.target.name]:e.target.value})
     }
    return (
    <>
    <div className='signupContainer'>
    <h1>강의생성</h1>
    <Form className='loginBox'>
    <Form.Group className="mb-3" controlId="formBasicEmail">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의명</Form.Label>
    <Form.Control type="text" placeholder="강의명 입력" name='title' value={info.title} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>선생님</Form.Label>
    <Form.Control type="text" placeholder="선생님" name='teacher' value={info.teacher} onChange={handleChange} />
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의설명</Form.Label>
    <Form.Control type="text" placeholder="강의설명" name='detail' value={info.detail} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>업로드</Form.Label>
    <Form.Control type="file" placeholder="upload" name='upload' accept='video/*' value={info.upload} onChange={handleChange}/>
    </Form.Group>
    <Button variant="outline-success" onClick={()=>{
    axios.post('http://localhost:3000/makeLecture',info).then((result)=>{
    console.log('성공이에요')
    alert("생성완료!")
    navigate('/lectureRoom') 
     })
     .catch(()=>{
    console.log('실패함')
     })
     }}>생성하기</Button>
    </Form>
    </div>
    </>
     )
    }
    export default MakeLecture
    <서버>
    
    app.post('/makeLecture',upload.single('upload'),function(req,res){
    const r = req.body
     
    db.collection('lecture_counter').findOne({name:'강의수'}, function(error,result){
    var totalLecture = result.totalLecture
    db.collection('lecture').insertOne({_id: totalLecture+1, title: r.title, teacher: r.teacher,
    detail: r.detail, maker:parseInt(totalLecture-1)},function(error,result){
    db.collection('lecture_counter').updateOne({name:'강의수'},{$inc:{totalLecture:1}},function(error,result){
    if(error) return console.log(error)
    res.send('전송완료')
     })
     })
     })
     }) // 강의생성
    
    이런 상태입니다.
    다만 state에 저장한값을 axios로 보내서 db에 저장하는 식인데 
    동영상 파일만은 노드js 서버에 저장하려합니다.
    다만 upload.single('upload')가 동작하지 않고 어떻게 수정하는게 좋을지 여쭤보고 싶습니다.
    구조는 이러합니다.
    
    
    
    #69828

    codingapple
    키 마스터
    파일업로드한거 출력하려면 e.target.files[0] 써야합니다
    https://stackoverflow.com/questions/72773040/why-i-cant-upload-file-in-reactjs
    이런거 참고합시다
    #69837

    강현우
    참가자
    그럼 multer에서의 name은 <Form.Control type="file" placeholder="upload" name='upload' accept='video/*' value={info.upload} onChange={handleChange}/> 에 있는것처럼
    upload.single('upload')로 하면 될까요?
    #69842

    강현우
    참가자
    import 'bootstrap/dist/css/bootstrap.min.css'; //bootstrap
    import {Nav, Navbar, Container,Button,Form} from 'react-bootstrap';
    import {useNavigate} from 'react-router-dom';
    import {useState} from 'react'
    import axios from 'axios';
    function MakeLecture(){
    let navigate = useNavigate();
    let [info,setInfo] = useState({
    id: 0,
    title:'',
    teacher:'',
    detail:'',
    upload:''
     })
    const handleChange = (e)=>{
    setInfo({...info,[e.target.name]:e.target.value})
     }
    const handleFileChange = (e) =>{
    setInfo({...info,[e.target.name]:e.target.files[0]})
     }
     
    return (
    <>
    <div className='signupContainer'>
    <h1>강의생성</h1>
    <Form className='loginBox'>
    <Form.Group className="mb-3" controlId="formBasicEmail">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의명</Form.Label>
    <Form.Control type="text" placeholder="강의명 입력" name='title' value={info.title} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>선생님</Form.Label>
    <Form.Control type="text" placeholder="선생님" name='teacher' value={info.teacher} onChange={handleChange} />
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의설명</Form.Label>
    <Form.Control type="text" placeholder="강의설명" name='detail' value={info.detail} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>업로드</Form.Label>
    <Form.Control type="file" placeholder="upload" name='upload' accept='video/*' value={info.upload} onChange={handleFileChange}/>
    </Form.Group>
    <Button variant="outline-success" onClick={()=>{
    axios.post('http://localhost:3000/makeLecture',info).then((result)=>{
    console.log('성공이에요')
    alert("생성완료!")
    navigate('/lectureRoom') 
     })
     .catch(()=>{
    console.log('실패함')
     })
     }}>생성하기</Button>
    </Form>
    </div>
    </>
     )
    }
    export default MakeLecture
    
    이런식으로 handleFileChange 함수를 추가 시켰습니다.
    그리고 서버에서 
    app.post('/makeLecture',upload.single('upload'),function(req,res){
    const r = req.body
    console.log(req.file)을 해보았지만 undefined가 나옵니다.
    넘어온 req.body는 알맞게 넘어왔습니다.
    undefined가 나오고 public 폴더에 저장도 안되는데 어떻게 해야할까요?
    
    
    p.s) 코드는 동일한데 갑자기 DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
        at HTMLInputElement.set [as value] 이런 에러가 나옵니다. 찾아보니 value를 지우라는데 지웠더니 서버로 넘어가는 state에 upload가 빈값으로 넘어갑니다
    #69870

    codingapple
    키 마스터
    value는 지워도 됩니다 ajax로 보낼거면 폼전송되면 안되니 <Form>태그도 지워봅시다
    #70002

    강현우
    참가자
    저게 bootstrap 긁어온건데 그럼 그냥 input으로 바꿀까요?
    #70030

    codingapple
    키 마스터
    #70114

    강현우
    참가자
    import 'bootstrap/dist/css/bootstrap.min.css'; //bootstrap
    import {Nav, Navbar, Container,Button,Form} from 'react-bootstrap';
    import {useNavigate} from 'react-router-dom';
    import {useState} from 'react'
    import axios from 'axios';
    function MakeLecture(){
    let navigate = useNavigate();
    let [info,setInfo] = useState({
    id: 0,
    title:'',
    teacher:'',
    detail:'',
    upload:''
     })
    const handleChange = (e)=>{
    setInfo({...info,[e.target.name]:e.target.value})
     }
    const handleFileChange = (e) =>{
    console.log(e.target.files[0])
    setInfo({...info,[e.target.name]:e.target.files[0]})
     }
    const SubmitData = () => {
    axios.post('http://localhost:3000/makeLecture',info).then((result)=>{
    console.log('성공이에요')
    alert("생성완료!")
    navigate('/lectureRoom') 
     }).catch(()=>{
    console.log('실패함')
     })
     }
     
    return (
    <>
    <div className='signupContainer'>
    <h1>강의생성</h1>
    <Form className='loginBox'>
    <Form.Group className="mb-3" controlId="formBasicEmail">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의명</Form.Label>
    <Form.Control type="text" placeholder="강의명 입력" name='title' value={info.title} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>선생님</Form.Label>
    <Form.Control type="text" placeholder="선생님" name='teacher' value={info.teacher} onChange={handleChange} />
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>강의설명</Form.Label>
    <Form.Control type="text" placeholder="강의설명" name='detail' value={info.detail} onChange={handleChange}/>
    </Form.Group>
    <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label style={{fontSize:'20px', fontWeight:'bold'}}>업로드</Form.Label>
    <input type="file" placeholder="upload" name='upload' accept='video/*' onChange={handleFileChange}/>
    </Form.Group>
    <Button variant="outline-success" onClick={SubmitData}>생성하기</Button>
     
    </Form>
    </div>
    </>
     )
    }
    export default MakeLecture
    
    쌤 말대로 input태그로 바꾸고 해보았는데 서버에서 req.body 해보면 { id: 0, title: 'ㅇ', teacher: 'ㅇ', detail: 'ㅇ', upload: {} } 이런식으로 파일 빠져있습니다.
    프론트단에서는 info가 다 알맞게 출력이 됩니다.
    질문드릴건 1. upload만 빠져있는데 어떻게 해야할지 2. upload.single은 만지는거 없이 그냥 input의 name 그대로 하면 될지 3. 저는 비디오 파일을 전송하려 하는데 Multer는 수정
    할게 없나요? react + node js 연동상태라서 Node 부분에서는 public 폴더가 안보이는데 경로를 일단 ./public/videos 로 해놨는데 맞게 했는지도 궁금합니다
    #70125

    codingapple
    키 마스터
    https://surajsharma.net/blog/react-upload-file-using-axios
    headers설정과 FormData()도 사용합시다
    
    저장할 폴더는 미리 서버에 만들어둡시다
    #70147

    강현우
    참가자
    그럼 파일만을 담는 state를 하나 더 만들어야 하나요
    아니면 info에다가도 파일을 넣어도 되나요?
    info에다 다 넣고 formdata로 넘겨도 그냥 state만 넘기는 것처럼 req.body하면 접근이 되나요?
10 글 보임 - 1 에서 10 까지 (총 20 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠