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

home2 게시판 Next.js 게시판 s3로 업로드하면 이런거 뜨는데

s3로 업로드하면 이런거 뜨는데

9 글 보임 - 1 에서 9 까지 (총 9 중에서)
  • 글쓴이
  • #83188

    정중식
    참가자
    
    
    아직 완전히 업로드 기능을 구현한건 아닌데요.... 좀 혼란스럽네요 이게 업로드기능을 구현한것인지 미리보기이미지 url을 구현한것인지..
    일단 강의에서처럼 FormData을 사용해주진않았습니다 테스트하려고 url만 확인했거든요
    
    
    console.log(url); 하면 뜨는 url이있어요 (제가 설정한버킷+파일이름이합쳐져있음)
    그걸 주소창에 넣으면 위의 사진처럼뜹니다.
    console.log(url);했을때 잘뜨면 설정은 잘 해준거같은데..
    강의에서처럼 url+'/'+파일이름 도 해줘봣는데 똑같습니다.
    
    설정이 잘못된걸까요?
    s3버켓에 이미지도 안올라가져있는데 이게 일단 지금은 정상인걸까요?
    
    s3버켓에 직접 이미지를 업로드시키고 url 클릭해보면 이미지는 잘보입니다
    
    
    #83207

    codingapple
    키 마스터
    S3에 이미지 안올라갔으면 이미지 미리보기도 불가능합니다 
    이미지 올리는 코드를 확인합시다
    #83235

    정중식
    참가자
    센세님..제 코드가 잘못된건지 한번 봐주실수있으실까요?
    
    Write.js 입니다.
    
    
    'use client';
    import { useState } from 'react';
    const Write = () => {
      const [imageURL, setImageURL] = useState('');
      const [imageFile, setImageFile] = useState('');
      const [title, setTitle] = useState('');
      const [contents, setContents] = useState('');
      const [src, setSrc] = useState('');
      const onFileUpload = (e) => {
        e.preventDefault();
        if (!e.target.files) return;
        const file = e.target.files[0];
        if (file) {
          let image = window.URL.createObjectURL(file);
          setImageURL(image);
          setImageFile(file);
        }
      };
      const onSubmit = async (e) => {
        e.preventDefault();
        if (imageFile) {
        }
        const fileName = encodeURIComponent(imageFile.name);
        const res = await fetch(`/api/post/new?file=${fileName}`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            title,
            contents,
          }),
        });
        const data = await res.json();
        setSrc(`${data.url}/${fileName}`);
        // 에러시
        if (res.status === 400) {
          alert(data);
        }
      };
      console.log(src);
      return (
        <div className='form-container'>
          <h4 className='title'>글작성페이지</h4>
          <form
            className='post-form'
            encType='multipart/form-data'
            onSubmit={onSubmit}
          >
            <input
              type='text'
              value={title}
              placeholder='글제목'
              onChange={(e) => setTitle(e.target.value)}
            />
            <textarea
              type='text'
              value={contents}
              placeholder='글내용'
              onChange={(e) => setContents(e.target.value)}
            />
            <input type='file' accept='image/*' onChange={(e) => onFileUpload(e)} />
            {imageURL && (
              <img
                src={imageURL}
                alt='미리보기이미지'
                style={{ marginBottom: '1rem' }}
              />
            )}
            <button type='submit'>글작성</button>
          </form>
        </div>
      );
    };
    export default Write;
    new.js로 api파일입니다..
    
    
    import { connectDB } from '@/util/database';
    import { getServerSession } from 'next-auth';
    import { authOptions } from '../auth/[...nextauth]';
    import aws from 'aws-sdk';
    export default async function handler(req, res) {
      let session = await getServerSession(req, res, authOptions);
      const { title, contents } = req.body;
      if (req.method === 'POST') {
        if (session) {
          if (title === '') {
            return res.status(400).json('제목을 작성해주세요.');
          }
          if (contents === '') {
            return res.status(400).json('내용을 작성해주세요.');
          }
          const newBody = {
            title,
            contents,
            author: session.user.email,
            postLikeCount: '0',
          };
          try {
            let client = await connectDB;
            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);
            // const result = await db.collection('post').insertOne(newBody);
            // res.redirect(302, '/');
          } catch (error) {
            res.status(500).json('에러발생', error);
            console.log('error:', error);
          }
        }
      }
    }
    완료되면 콘솔에 파일 url+파일이름 잘 뜨는데 새탭으로 클릭해서 열어보면 계속 처음 질문의 이미지처럼 에러를 뱉어요
    
    #83239

    codingapple
    키 마스터
    S3사이트에 이미지 올라간거 눌러서 주소는어떻게 되나 콘솔창에뜨는거랑 비교해봅시다
    #83248

    정중식
    참가자
    선생님 답변 감사합니다.
    
    제가 강의보면서 만든 사이트에서 올린 이미지 주소는
    
    https://s3.ap-northeast-2.amazonaws.com/nextjs-codingapple/me.png (에러나옴)이렇고,
    
    
    s3 버켓에 직접 올린 이미지 url은
    
    https://nextjs-codingapple.s3.ap-northeast-2.amazonaws.com/me.png (정상적으로 나옴)
    이렇습니다.
    
    차이가 좀 있는데 이러면 안되는건가요?
    똑같아야하는거죠..?
    
    혹시몰라서 제가 권한설정한것도 올리겠습니다.
    
    1.
    
    
    2.
    
    
    
    
    #83291

    codingapple
    키 마스터
    프론트엔드에서 이미지 보여줄 때 https://nextjs-codingapple.s3.ap-northeast-2.amazonaws.com + 이미지이름 해서 사용합시다
    #83300

    정중식
    참가자
    선생님 혹시,  s3 업로드 코드전에 그러니까 아래 코드처럼, url만 얻는 코드까지 했을때, url을 얻으면서 s3버켓에 이미지가 저장되어있어야하는건가요?
    
    
    
    'use client';
    import { useState } from 'react';
    const Write = () => {
      const [src, setSrc] = useState('');
      return (
        <div className='p-20'>
          <h4>글작성</h4>
          <form action='/api/post/new' method='POST'>
            <input name='title' placeholder='글제목' />
            <input name='content' placeholder='글내용' />
            <button type='submit'>전송</button>
          </form>
          <input
            type='file'
            accept='image/*'
            onChange={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();
              setSrc(res.url + '/' + filename);
              console.log(src);
         
          />
          < img src={src} />
        </div>
      );
    };
    export default Write;
    
    
    #83301

    정중식
    참가자
    선생님 IAM 권한 문제일수도있을까요? 저는 아래 사진처럼 권한을 준 상태인데 여기서 더 추가해야하는게 있을까요?
    
    https://repost.aws/ko/knowledge-center/s3-403-forbidden-error 이곳에서는 
    
    s3:PutObject 또는 s3:PutObjectAcl 작업에 대한 권한이 있는지 확인합니다.
    
    라고 하는데, IAM=>사용자=>jung(제가 만든사용자) 클릭 => 권한추가 => 검색 s3:PutObject 혹은 s3:PutObjectAcl을 검색해보면 안뜹니다..
    
    선생님도 바쁘실텐데 계속 귀찮게해드려 죄송합니다. 나름대로 스스로 해결해보고자 계속 붙들고있는데 안되네요..
    
    
    
    #83329

    정중식
    참가자
    아 이런 선생님 제가 .. 제가....
    
    못난 제자를 용서해주십시오!!! 크흑...
    
    
    
    제가 멍청했습니다..
    
    url받아오면 다 만사오케이인줄알았어요..
    
    폼데이터로 s3에 파일명,파일정보를 전송까지 해줘야 s3에 업로드가 되는거였군여!!!!!!
    
    
    
    분합니다.. 이까짓걸로 어제오늘 이틀이나 소비하다니요
9 글 보임 - 1 에서 9 까지 (총 9 중에서)
  • 답변은 로그인 후 가능합니다.

About

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

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

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