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

home2 게시판 Next.js 게시판 이미지2 회차 오타발견이요.

이미지2 회차 오타발견이요.

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

    이오디
    참가자
    영상 2:42 지점입니다.
    영상엔 정상적으로 기재되어있는데
    
    예시 코드에는 = 가 누락되어있습니다.
    fetch('URL?file=' + filename) 부분에 = 이 없네요.
    
    
     
    
    #83302

    정중식
    참가자
    님, 글과는 무관한 얘기인데, 혹시 aws s3 이미지 업로드 잘되시나요?
    버켓 세팅, 권한 설정 cors 등등 강의대로 하고 그다음에 IAM설정은 어떻게 주셨는지 공유해주시면 안될까요ㅠㅠ
    어제오늘 계속 헤매고있습니다..
    #83303

    이오디
    참가자
    저도 어제까지 이미지 업로드 안 되었습니다. 영상대로 따라했었는데, 
    콘솔 로그 찍어보면 개발자도구에 203번이 아니라 400번 뜨더라고요.
    
    버켓 셋팅, 권한 설정, cors 등등 모두 영상과 동일합니다. 그러다보니 공유드려도 버킷 이름 같은 것 말고는 차이가 없을 것입니다.
    
    제가 어제 s3 이미지 업로드 실패했던 이유는 fetch 주소를 잘못 기재해서 그런 것으로 파악했습니다.
    fetch('/api/post/image?file=' + filename) 로 수정하니까 정상적으로 업로드 되었습니다.
     
    #83304

    이오디
    참가자
    혹시 어떻게 실패하시는지요?
    저는 'use client' 선언하면서 서버에서 사용할 수 있는 코드를 못 썼던 것도 문제가 되긴 했습니다.
    
    그래서  write 폴더 내에 컴포넌트를 새로 만들었습니다. 
    // /write/page.js
    import { connectDB } from "@/util/database"
    import { getServerSession } from "next-auth";
    import { authOptions } from "@/pages/api/auth/[...nextauth]";
    import WriteForm from "./WriteForm"
    export default async function Write() {
      let session = await getServerSession(authOptions)
      if (!session) {
        return (
          <div>
            <h4>로그인 후 작성이 가능</h4>
          </div>
        );
      } else {
        return (
          <div className="list-bg">
            <WriteForm/>
          </div>
        );
      } 
    }
    // /write/WriteForm.js
    'use client'
    import { useState } from "react"
    export default async function WriteForm() {
      let [src, setSrc] = useState('')
      
      const fileChange = async (e) => {
        let file = e.target.files[0] // 유저 파일명
        let filename = encodeURIComponent(file.name) //한글 파일명
        let res = await fetch('/api/post/image?file=' + filename)
        res = await res.json()
      //S3 업로드
      const formData = new FormData()
      Object.entries({ ...res.fields, file }).forEach(([key, value]) => {
        formData.append(key, value)
      })
      const uploadResult = await fetch(res.url, {
        method: 'POST',
        body: formData,
      })
      if (uploadResult.ok) {
        setSrc(uploadResult.url + '/' + file.name)
      } else {
        console.log('실패')
      }}
      
      return (
        <div className="p-20">
          <h4>글작성</h4>
          <form action="/api/post/new" method="POST">
            <input name="title" placeholder="글제목" />
            <input name="content" placeholder="글내용" />
            <input type="file" accept="image/*" onChange={fileChange} />
            <input name="content" placeholder="글내용" />
            < img src={src} />
            <button type="submit">전송</button>
          </form>
        </div>
      )
      }
    #83305

    이오디
    참가자
    오류코드, 실패 메시지가 있다면 올려주세요~
    #83308

    정중식
    참가자
    답변감사합니다.
    
    저는
    setSrc(uploadResult.url + '/' + file.name); 후에
    console.log(src);하면 나오는 url을 클릭하면 새텝으로 에러페이지가 나옵니다.
    
    
    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <Error>
    NoSuchKey
    <Message>The specified key does not exist.</Message>
    <Key>test.jpg</Key>
    <RequestId>....</RequestId>
    <HostId>...</HostId>
    </Error>
    이런 에러요.. 
    
    아마 버켓에 이미지가 저장이안되서, 찾아올 수 없는거같은데 
    
    저장은 왜 안되는지 모르겠네요..
    
    버켓에 이미지를 직접 업로드하고 객체URL로 확인해보면 이미지는 정상로드됩니다.
    
    그래서 버켓 세팅은 잘 된거같은데.. 코드가 잘못된걸까요?
    
    프론트에서 아래 코드처럼 해줬고,
    
      const [src, setSrc] = useState('');
      const onFileUpload = async (e) => {
        const file = e.target.files[0];
        const filename = encodeURIComponent(file.name);
        const res = await fetch('/api/post/image?file=' + filename);
        const data = await res.json();
        setSrc(`${data.url}/${filename}`);
      };
    
    백엔드쪽은 이렇게 되어있습니다.
    
    
    import aws from 'aws-sdk';
    export default async function handler(req, res) {
      aws.config.update({
        accessKeyId: process.env.ACCESS_KEY,
        secretAccessKey: process.env.SECRET_KEY,
        region: 'ap-northeast-2',
        signatureVersion: 'v4',
      });
      const s3 = new aws.S3();
      const url = await s3.createPresignedPost({
        Bucket: process.env.BUCKET_NAME,
        Fields: { key: req.query.file },
        Expires: 60, // seconds
        Conditions: [
          ['content-length-range', 0, 1048576], //파일용량 1MB 까지 제한
        ],
      });
      console.log(url);
      res.status(200).json(url);
    }
    
    
    혹시나 의심될만한게 있으시다면 .. 아니라도 상관없으니깐 편하게 적어주시면 정말 감사하겠습니다
    #83314

    이오디
    참가자
    기존 버킷을 삭제하고, 영상보면서 따라하시면서 다시 생성하셔도 동일하게 문제 발생하시는 거죠?답답하시겠네요.
    #83317

    정중식
    참가자
    공감해주셔서 감사합니다. 
    혹시 하나만 더 여쭤봐도될까요? 
    님도 혹시 글로벌로 되어있을까요? 영상 처음부터 찬찬히 보는중인데 
    선생님은, 서울로 설정하라고하시는데 저는 글로벌로 되어있고 서울로 선택이안되네요
    
    리전관리들어가서 보면  기본적으로 활성화됨이라고 나와있기는한데..
    
    
    
    님은 어떻게되어있으신가요?
    #83326

    이오디
    참가자
    그 글로벌 부분은 님과 동일합니다. 버킷 생성은 서울로 했고요.
    #83330

    정중식
    참가자
    감사합니다. 해결했어요
    
    url만 받아오면 만사오케이인줄알았는데..
    
    
        const formData = new FormData();
        Object.entries({ ...res.fields, file }).forEach(([key, value]) => {
          formData.append(key, value);
        });
        let 업로드결과 = await fetch(res.url, {
          method: 'POST',
          body: formData,
        });
        console.log(업로드결과);
        if (업로드결과.ok) {
          setSrc(업로드결과.url + '/' + filename);
        } else {
          console.log('실패');
        }
    이 코드까지 작성해줘야 버킷에 업로드가 되는거였군요 ...; 
    역시 그냥 강의따라서 처음부터끝까지 따라쳐보고 그다음에 응용을 하던가 해야겠어요
    자만해서 처음부터 응용해서 코드 치다가.. 하 ..
10 글 보임 - 1 에서 10 까지 (총 11 중에서)
  • 답변은 로그인 후 가능합니다.

About

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

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

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