묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
nodebird 프로필 수정 기능 구현 시, 에러가 발생했을 때 에러처리미들웨어에서 res.render('error')가 안되는 상황
프로필 수정 기능을 구현하기 위한 profileUpdate.html{% extends 'layout.html' %} {% block content %} <div class="timeline"> <form id="profile-update-form"> <!-- <div class="input-group"> <label for="join-email">이메일</label> <input id="join-email" type="email" name="email" /> </div> --> <div class="input-group"> <label for="join-nick">닉네임</label> <input id="join-nick" type="text" name="nick" /> </div> <div class="input-group"> <label for="join-password">비밀번호</label> <input id="join-password" type="password" name="password" /> </div> <button id="join-btn" type="submit" class="btn">수정</button> </form> </div> {% endblock %} {% block script %} <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> window.onload = () => { const errorParam = new URL(location.href).searchParams.get('error'); if (errorParam) { alert(errorParam); } }; if (document.getElementById('profile-update-form')) { document.addEventListener('submit', async (event) => { event.preventDefault(); const formData = new FormData(event.target); const config = { headers: { 'content-type': 'application/json', }, }; axios .put('/profile/update', formData, config) .then((res) => { alert('프로필 정보가 수정되었습니다.'); window.location.href = '/profile'; }) .catch((error) => { alert(error); }); }); } </script> {% endblock %} 그리고 controller/page.jsexports.renderProfileUpdate = (req, res, next) => { res.render('profileUpdate', { title: '내 정보 수정 - NodeBird' }); }; exports.profileUpdate = async (req, res, next) => { try { const { nick, password } = req.body; const id = req.user.id; const exUser = await User.findOne({ where: { id } }); if (!exUser) { throw new Error('존재하지 않는 사용자입니다.'); // res.status(404).send('no user'); } const sameNickUser = await User.findOne({ where: { nick, id: { [Op.ne]: exUser.id, }, }, }); if (sameNickUser) { throw new Error('중복된 닉네임입니다.'); // res.status(501).send('중복된 닉네임입니다.'); } const hash = await bcrypt.hash(password, 12); exUser.set({ nick, password: hash, }); await exUser.save(); res.status(201).send(); } catch (error) { console.error(error); next(error); } };app.js의 에러처리 미들웨어app.use((err, req, res, next) => { // 404 다음은 에러처리 미들웨어 console.error('에러는 ', err.message); res.locals.message = err.message; res.locals.error = process.env.NODE_ENV !== 'production' ? err : {}; // 보안상 위험(오히려 배포 시 사용자 화면에 에러를 숨김) // 에러를 로깅 서비스에 넘김 res.status(err.status | 500); res.render('error'); // views/error.html });일부러 중복된 닉네임을 넣어 라우터에서 에러를 발생시켰을 때, 에러처리미들웨어의 console.error('에러는 ', err.message); 부분에서 "Error: 중복된 닉네임입니다. at exports.profileUpdate (/nodestudy/nodebird/controllers/page.js:31:13) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)에러는 중복된 닉네임입니다.PUT /profile/update 500 10.568 ms - 1862" 로 에러 메시지가 정상적으로 찍히는 것을 확인하였습니다.preview 탭에선 정상적으로 나오는 것 같은데, 실제 브라우저 화면에선 위와 같이 뜨면서 제가 원하는 에러 메시지('중복된 닉네임입니다')가 alert 창에 뜨지 않으며, error.html이 렌더링도 되지 않고 있습니다. 구글링해봐도 제가 잘 못한건지 이유를 못찾겠습니다🥲 제가 뭘 놓친걸까요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
connect.sid를 쿠키에 넣는 시점과 express-session
req.login를 통해 req.session에 { 랜덤값: 유저아이디}를 저장하는 건 알겟는데, connect.sid=랜덤값을 쿠키에 넣는 시점은 언제인가요?그리고 서버가 connect.sid를 세션 쿠키로 전송할 때, express-session 은 자동으로 이 값을 secret으로 서명하여 전송하나요?
-
미해결[웹 개발 풀스택 코스] Node.js 프로젝트 투입 일주일 전 - 기초에서 실무까지
sql버전안맞음
저의 경우 client sql 버전이 안맞다고 나옵니다 workbench는 8.0Mysql 9.0 Configurator로 설치했습니다 stackoveflow에서 찾아보니ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';Where root as your user localhost as your URL and password as your passwordThen run this query to refresh privileges:flush privileges;Try connecting using node after you do so.If that doesn't work, try it without @'localhost' part. 이런 답변이 있는데 어떻게 적용하는지 알 수 있을까요?
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
express.static의 요청 처리
app.use('/', express.static(path.join(__dirname, 'public')));다른 코드들에서는 이런 식으로 경로를 지정하면 경로와 똑같은 요청만 처리를 하거나 모든 요청에 대해 처리하고 싶으면 그냥 경로를 생략하였는데 express.static은 왜 localhost:3000/ 에 대한 요청만 받아들이는 것이 아니라, 모든 요청에 대해 해당 파일이 있는지 확인하게 되는지 궁금합니다. 예시)localhost:3000/about -> public 폴더 안에 about 파일이 있는지 찾음 localhost:3000/hello.css-> public 폴더 안에 hello.css 파일이 있는지 찾음express.static은 특별한 미들웨어 인가요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
`app.use`의 용도에 대해 질문 드립니다!
궁금한 점이 있습니다. 지금까지는 다음과 같이 app.use 안에 요청 처리를 위한 미들웨어를 작성했는데, app.use((req, res, next) => { console.log("모든 요청에 실행하고 싶어요"); next(); });다음과 같이 app.use에 다운받은 미들웨어를 장착하는 건 "이 파일에서 특정 미들웨어를 사용하겠다"는 의도로 사용하는 건가요?? 아니면 둘 다 같은 동작을 하는건데 제가 둘을 다르다고 생각하는 걸까요?app.use(morgan("dev")); app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true }));추가로, 위 미들웨어들로 인해 req이나 res 객체에서 편하게 .cookie나 .body를 사용할 수 있게 되는데 그럼 미들웨어 내에서 미들웨어를 사용하는 건가요 🤔🤔?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
어떤 객체가 이벤트를 발생시키는지
여러 챕터에서 객체의 on 메서드를 사용하는 코드가 자주 보여서 개념에 대해 알아보았습니다.const fs = require("fs"); console.log("before:", process.memoryUsage().rss); // 메모리 체크 // 스트림 방식으로 파일 읽고 보내기 const readStream = fs.createReadStream("./big.txt"); const writeStream = fs.createWriteStream("./big3.txt"); readStream.pipe(writeStream); readStream.on("end", () => { console.log("stream: ", process.memoryUsage().rss); });그런데 이렇게 이벤트가 발생하는 객체의 종류를 모두 외우고 있어야 하나요? 아니면 이 객체가 이벤트를 발생시키는지 예상(?), 판단할 수 있는 기준이 있나요?
-
해결됨하루만에 배우는 express with AWS
postgresql connect() 문제
강의내용에 추가내용으로 환경설정 업데이트가 되어야할것 같습니다.... 환경설정으로 시간을 허비하는군요. 연결 관련으로const pool = new Pool({ host: "", user: "", port: , password: "",});ssl 인증서 허용 옵션을 풀어야 연결이 되었습니다. const pool = new Pool({ host: "", user: "", port: , password: "", ssl: { rejectUnauthorized: false, },});
-
미해결하루만에 배우는 express with AWS
reqbin에서 POST 할때 404 content Something went wrong나타납니다.
다음과 같은 양식으로 남겨주세요.질문을 한 배경 : 설정문제인지 여러번했는데 틀린 곳을 찾을 수 없어 질문드립니다.질문내용 reqbin에서 POST 할때 404 content Something went wrong나타납니다. get 부분 post부분 확인 부탁드립니다.
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
CORS 질문 있습니다.
안녕하세요.CORS 에러를 해결하고 있는데, 잘 이해가 가지 않는게 있어서 질문 드립니다.CORS 문제를 해결하기 위해서 이런식으로 Nginx에서 헤더를 달아 줄 수 있도록 설정해뒀습니다.그런데 PATCH, DELETE 요청에서 CORS 에러가 발생합니다. GET, POST 요청은 정상적으로 잘 가는데 말이죠Access to XMLHttpRequest at '[요청 URL]' from origin '[도메인 원본]' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.이렇게 콘솔에 찍히는데, Access-Control-Allow-Credentials 헤더가 안달려서 발생한다는 내용이길래, PATCH, DELETE 메소드일 경우에는 필요한 헤더를 달아 줄 수 있도록 수정해서 설정을 바꿔보면 이번엔 Access-Control-Allow-Origin 헤더가 누락되는 등 문제가 발생하고 있습니다.-- 일반 -- Request URL: [요청 URL] Request Method: PATCH Status Code: 403 Forbidden Referrer Policy: strict-origin-when-cross-origin --응답헤더-- Access-Control-Allow-Origin: [도메인 원본] Cf-Cache-Status: DYNAMIC Cf-Ray: Content-Encoding: br Content-Type: text/html Date: Server: 분명 잘 되던게 갑자기 이렇게 문제가 발생하는것도 이상한데, 같은 서버 설정, 같은 코드로 배포하고 있는 다른 서버에서는 정상적으로 모든 요청이 잘 이루어지고 있습니다.대체 어디를 확인해야 할지 모르겠습니다...
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
쿠키 옵션에 대해서 질문 있습니다.
안녕하세요. 백엔드 서버와 클라이언트가 사용하는 도메인이 달라서, 쿠키의 samesite 옵션을 none으로 주고, secure 옵션을 true로 설정해서 사용하고 있습니다. 클라이언트와 서버가 쿠키를 잘 주고받고 있는 것으로 보이는데, 문득 현업에서는 어떻게 옵션을 설정해서 사용하는지 궁금해져서 게시글 남기게 되었습니다. 현업에서는 혹시 도메인이 다른 경우 쿠키 옵션을 어떻게 설정해서 사용하나요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
논 블로킹 방식의 동작 원리 이해가 어렵습니다.
강의 교안의 논 블로킹의 정의와 책의 예제(setTimeout 함수를 이용해 작업 시간이 긴 함수를 백그라운드로 보냄)를 읽어 보면오래 걸리는 함수를 백그라운드로 보내는 것 같은데, 그 다음 설명을 보면일부 코드들이 백그라운드에서 병렬로 실행된다고 되어있어서 헷갈립니다. 위 내용을 바탕으로 제가 이해한 것은 작업 시간이 긴 함수, 일부 코드 모두 백그라운드로 전달작업 시간이 긴 함수는 태스크 큐로 전달되고 동시 작업이 가능한 일부 코드들은 백그라운드에서 병렬로 처리일부 코드들의 병렬 처리가 끝나고 나면 태스크 큐에 있는 (블로킹 방식의)작업 시간이 긴 함수 처리 인데 맞을까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Next 14 사용해도 될까요?
궁금합미다
-
미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
Presigned URL 사용시 데이터베이스 저장 시점
데이터베이스 저장 시점현재 이미지 업로드 관련해서 프로젝트를 진행하고있는데, 이미지를 불러오기 위해 별도의 데이터베이스 저장이 필요해서 클라이언트에서 presigned URL을 사용하여 이미지 업로드가 완료된 후, 서버에 이미지 이름과 부가적인 정보를 보내주면 서버가 이를 데이터베이스에 저장하는 방식으로 구현하는게 맞을까요??
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
강의 다 듣고 수료증 받을 수 있죠?
강의 다 들으면 수료증 받을 수 있죠?제출해야되서요..
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
소셜로그인 User 테이블 관련 질문 있습니다.
소셜로그인을 구현하다가 의문점이 생긴 부분이 있어 어떠한 방식으로 접근하는 것이 궁금하여 질문을 남깁니다.상황일반 회원가입시에는, 이메일 비밀번호 + 해당 서비스에 필요한 필수 정보들을 받고, 해당 내용을 클라이언트로 부터 받아 user테이블에 저장하는 상황입니다.소셜 로그인 같은 경우에는, 정보를 받을 수 있는 것이 제한이 되어있어, 추가적으로 필요한 정보들을, 소셜 로그인 성공 이후, 클라이언트 측에서 회원가입시 필요한 정보들을 받을 수 있는 화면으로 이동시켜, 해당 정보를 받아서, 부족한 정보들을 채워넣는 것으로 알고 있습니다.궁금점.소셜로그인 로그인 후, 신규 유저이기에 서비스 이용에 필요한 필수 부가정보 입력을 받기위해, 회원가입 창으로 이동시켜, 부가 정보를 입력받는다면 크게 문제가 없습니다.하지만, 앱을 사용하다보면은 데이터가 끊긴다거나, 배터리가 방전된다거나, 알수없는 이유로, 로그인은 되었으나, 필수 부가정보를 입력하지 못하고, 꺼지는 경우가 있습니다. 필수 부가정보를 꼭 받아야 하는 경우라면 이 부분에 대해서 어떻게 처리해야하나요?필수 정보를 채웠는지 여부를 확인하는 column을 boolean으로 User 테이블에 추가하여, 클라이언트에서 해당 Column으로 부가정보를 입력받지 않았으면 메인화면으로 가지않고, 회원가입 스크린으로 리다이렉 시키는 이런 로직을 작성해야하나요?필수 정보를 채웠는지 여부를 확인하는 column 없이 이런 경우에 처리할 수 있는 방안이 있는지 궁금하고, 현업에서는 어떤식으로 테이블을 설계하는지 궁금합니다!
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
SequelizeEagerLoadingError: User is not associated to Post!
안녕하세요 제로초님, User 테이블이랑 Post테이블이 관계설정이 안되어있다는 에러가 떠서 문의드립니다. 분명 시퀄라이즈 관계설정하는 부분 빠짐없이 모두 따라했는데 이런 오류가 뜹니다.
-
미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
이미지 등록시 자동 등록 오류
이미지 등록시에 아래 사진과 같이 이미지가 리스트에 등록이 되긴하는데 이미지 형태가 깨져서 등록이 됩니다. 새로고침을 해야 정상적으로 반영되는 오류가 있는데 어느 코드가 잘못된지를 모르겠습니다ㅠㅠhttps://github.com/jjeongdong/ImageUpload_front
-
미해결습관부터 바꿔주는 Node.js & Express 기초
nodemon -exce 관련 오류가 나오실 때
nodemon -x babel-node src/index.js --extensions \".js,.jsx,.ts,.tsx\" --watch src위 명령어로 실행하시면 됩니당
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
경매 진행 메인 화면에서 오류 발생
경매 코드를 작성한 후 동작을 시켰을 때 메인 화면에 아래 그림과 같은 에러가 발생 하였습니다에러 발생 부분의 코드는 controllers/index.js 파일 부분인데 특별한 오류 점을 찾을 수가 없어 (작성한 파일들은 guithub 에 올려주신 파일들과 비교할 때 틀린 점을 발견하지 못함) 강사님께 문제 해결을 위해 질문 드립니다 해당 코드 부분try { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); //어제시간 const goods = await Good.findAll( { where: { SoldId: null, createdAt: { [Op.gte] : yesterday} }, }); res.render ('main', { title: 'NodeAuction', goods, });에러 로그 내용:Error at Query.run (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\sequelize\lib\dialects\mysql\query.js:52:25) at D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\sequelize\lib\sequelize.js:315:28 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async MySQLQueryInterface.select (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\sequelize\lib\dialects\abstract\query-interface.js:407:12) at async Good.findAll (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\sequelize\lib\model.js:1140:21) at async exports.renderMain (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\controllers\index.js:7:19) { name: 'SequelizeDatabaseError', parent: Error: Unknown column 'Good.SoldId' in 'where clause' at Packet.asError (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\packets\packet.js:728:17) at Query.execute (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\commands\command.js:29:26) at Connection.handlePacket (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:481:34) at PacketParser.onPacket (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:97:12) at PacketParser.executeStart (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\packet_parser.js:75:16) at Socket.<anonymous> (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:104:25) at Socket.emit (node:events:518:28) at addChunk (node:internal/streams/readable:559:12) at readableAddChunkPushByteMode (node:internal/streams/readable:510:3) at Readable.push (node:internal/streams/readable:390:5) { code: 'ER_BAD_FIELD_ERROR', errno: 1054, sqlState: '42S22', sqlMessage: "Unknown column 'Good.SoldId' in 'where clause'", sql: "SELECT `id`, `name`, `img`, `price`, `createdAt`, `updatedAt`, `deletedAt` FROM `goods` AS `Good` WHERE (`Good`.`deletedAt` IS NULL AND (`Good`.`SoldId` IS NULL AND `Good`.`createdAt` >= '2024-07-02 01:58:59'));", parameters: undefined }, original: Error: Unknown column 'Good.SoldId' in 'where clause' at Packet.asError (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\packets\packet.js:728:17) at Query.execute (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\commands\command.js:29:26) at Connection.handlePacket (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:481:34) at PacketParser.onPacket (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:97:12) at PacketParser.executeStart (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\packet_parser.js:75:16) at Socket.<anonymous> (D:\Javascript_Work\node_works\node_js_3\skyc_work\node_auction\node_modules\mysql2\lib\connection.js:104:25) at Socket.emit (node:events:518:28) at addChunk (node:internal/streams/readable:559:12) at readableAddChunkPushByteMode (node:internal/streams/readable:510:3) at Readable.push (node:internal/streams/readable:390:5) { code: 'ER_BAD_FIELD_ERROR', errno: 1054, sqlState: '42S22', sqlMessage: "Unknown column 'Good.SoldId' in 'where clause'", sql: "SELECT `id`, `name`, `img`, `price`, `createdAt`, `updatedAt`, `deletedAt` FROM `goods` AS `Good` WHERE (`Good`.`deletedAt` IS NULL AND (`Good`.`SoldId` IS NULL AND `Good`.`createdAt` >= '2024-07-02 01:58:59'));", parameters: undefined }, sql: "SELECT `id`, `name`, `img`, `price`, `createdAt`, `updatedAt`, `deletedAt` FROM `goods` AS `Good` WHERE (`Good`.`deletedAt` IS NULL AND (`Good`.`SoldId` IS NULL AND `Good`.`createdAt` >= '2024-07-02 01:58:59'));", parameters: {} }
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
로그아웃 요청이 403 forbidden 에러가 나는데 왜그런걸까요??
"success": false, "code": 403, "data": "Forbidden resource"이렇게 에러가납니다.@ApiCookieAuth('connect.sid') @UseGuards(LoggedInGuard) @Post('logout') async logout(@Res() res) { console.log(res); res.clearCookie('connect.sid', { httpOnly: true }); return res.send('ok'); } 프론트에서는 const logoutMutation = useMutation({ mutationFn: () => { return api.post("/api/teachers/logout"); }, onSuccess: (res) => { localStorage.removeItem("teacherState"); router.push("/auth/login"); }, onError: (error) => { console.log(error); }, });이런식으로 보내고있거든요 api는 axios에 credentials: true 와함꼐 보내고있습니다.