묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
전체적인 테이블 구조를 알 수 있을까요?
ERD와 함께 보는게 이해하기 편할것 같은데 혹시 이미지 첨부해주실수 있으신가요?
-
미해결스프링 핵심 원리 - 기본편
컴포넌트 스캔 파트 문의
1. @Component는 붙이고, @Autowired는 붙이지 않아도 자동으로 DI가 작동해서 테스트에서 에러가 나지 않아요... 어떻게 작동하는 것일까요? --> 그 다음 챕터 강의로 해결했습니다 2. @Configuration을 "스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다"는 부분이 어떤 의미인지 궁금합니다. 다른 Component 계열 어노테이션들(ex. @Service)도 별도 옵션을 두지 않으면 싱글톤 빈을 만든다고 이해했는데 아닌가요?
-
미해결실전! 웹사이트제작! Step By Step! _Basic (한화캐미컬_반응형웹)
리셋 css 적용 시 사소한 문제가 있습니다.
영상 아래의 /*reset*/ 을 복사하여 붙여 넣으면 img {vertical-align: middle;}인해 영상 11분 59초에 나오는 paddig-top 15px 때문에 가운데로 오지 않고 로고가 아래로 쳐지게 됩니다.
-
미해결Python 부트캠프
홈페이지 링크 부탁드립니다.
초반에 나오는 페이지를 볼 수 있는 방법 부탁드려요ㅠㅠ
-
미해결애플 웹사이트 인터랙션 클론!
scroll-section 1에서 2로 넘어갈때 잠깐 텍스트들이 뜹니다
(() => { let yOffset = 0; // window.pageYOffset 대신 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화된(눈 앞에 보고있는) 씬(scroll-section) let enterNewScene = false; // 새로운 scene이 시작된 순간 true const sceneInfo = [ { // 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d') }, values: { messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_in: [20, 0, { start: 0.7, end: 0.8 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }], messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }], messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageA_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] } }, { // 1 type: 'normal', // heightNum: 5, // type normal에서는 필요없음 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1') } }, { // 2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2'), messageA: document.querySelector('#scroll-section-2 .a'), messageB: document.querySelector('#scroll-section-2 .b'), messageC: document.querySelector('#scroll-section-2 .c'), pinB: document.querySelector('#scroll-section-2 .b .pin'), pinC: document.querySelector('#scroll-section-2 .c .pin') }, values: { messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageB_translateY_in: [30, 0, { start: 0.6, end: 0.65 }], messageC_translateY_in: [30, 0, { start: 0.87, end: 0.92 }], messageA_opacity_in: [0, 1, { start: 0.25, end: 0.3 }], messageB_opacity_in: [0, 1, { start: 0.6, end: 0.65 }], messageC_opacity_in: [0, 1, { start: 0.87, end: 0.92 }], messageA_translateY_out: [0, -20, { start: 0.4, end: 0.45 }], messageB_translateY_out: [0, -20, { start: 0.68, end: 0.73 }], messageC_translateY_out: [0, -20, { start: 0.95, end: 1 }], messageA_opacity_out: [1, 0, { start: 0.4, end: 0.45 }], messageB_opacity_out: [1, 0, { start: 0.68, end: 0.73 }], messageC_opacity_out: [1, 0, { start: 0.95, end: 1 }], pinB_scaleY: [0.5, 1, { start: 0.6, end: 0.65 }], pinC_scaleY: [0.5, 1, { start: 0.87, end: 0.92 }] } }, { // 3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++) { if (sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; } else if (sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight; } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } yOffset = window.pageYOffset; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++) { totalScrollHeight += sceneInfo[i].scrollHeight; if (totalScrollHeight >= yOffset) { currentScene = i; break; } } document.body.setAttribute('id', `show-scene-${currentScene}`); } function calcValues(values, currentYOffset) { let rv; // 현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; if (values.length === 3) { // start ~ end 사이에 애니메이션 실행 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd) { rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1]- values[0]) + values[0]; } else if (currentYOffset < partScrollStart) { rv = values[0]; } else if (currentYOffset > partScrollEnd) { rv = values[1]; } } else { rv = scrollRatio * (values[1]- values[0]) + values[0]; } return rv; } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene) { case 0: // console.log('0 play'); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); if (scrollRatio <= 0.32) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.67) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.93) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } function scrollLoop() { enterNewScene = false; prevScrollHeight = 0; for (let i = 0; i < currentScene; i++) { prevScrollHeight += sceneInfo[i].scrollHeight; } if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (yOffset < prevScrollHeight) { enterNewScene = true; if (currentScene === 0) return; // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) currentScene --; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); // DOMContentLoaded : HTML구조만 로드되면 바로 실행, 실행타이밍 빠름 window.addEventListener('load', setLayout); window.addEventListener('resize', setLayout); })(); 보통스크롤영역이 있는 scroll-section1에서 2로 넘어갈때 순간적으로 텍스트들과 핀이 잠깐 떳다가 사라집니다. 이게 처음 새로고침했을때만 나타나고 한번 지나가고나면 안나타납니다. 그리고 이렇게 이 부분은 원래 이렇게 다음섹션으로 넘어갈때 침범하는게 맞는건가요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
오류
events.js:291 throw er; // Unhandled 'error' event ^ Error: listen EADDRINUSE: address already in use :::5000 at Server.setupListenHandle [as _listen2] (net.js:1317:16) at listenInCluster (net.js:1365:12) at Server.listen (net.js:1451:7) at Function.listen (C:\Users\ivy\bolier-plate\node_modules\express\lib\application.js:618:24) at Object.<anonymous> (C:\Users\ivy\bolier-plate\index.js:29:5) at Module._compile (internal/modules/cjs/loader.js:1085:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) at Module.load (internal/modules/cjs/loader.js:950:32) at Function.Module._load (internal/modules/cjs/loader.js:791:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47 Emitted 'error' event on Server instance at: at emitErrorNT (net.js:1344:8) at processTicksAndRejections (internal/process/task_queues.js:80:21) { code: 'EADDRINUSE', errno: -4091, syscall: 'listen', address: '::', port: 5000 } npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! bolier-plate@1.0.0 start: `node index.js` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the bolier-plate@1.0.0 start script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\ivy\AppData\Roaming\npm-cache\_logs\2020-10-04T08_54_51_132Z-debug.log 처음에 실행할때는 잘 되는데 다시 실행하려고하면 계속해서 똑같은 오류가 나요 해결하려고 별짓을 다해봤는데 안되네요 왜 그런걸까요??
-
해결됨스프링 시큐리티
statefull vs stateless 질문
안녕하세요. BasicAuthenticationFilter 설명에 오류가 있는것 같아 질문 남깁니다. 확인 부탁드려요. BasicAuthenticationFilter.doFilterInternal 메소드 안에 this.rememberMeServices.loginSuccess(request, response, authResult);가 호출되는 부분이 있는데 여기에서 쿠기가 발급되는 것 같습니다. 그리고 postman을 이용해서 basic authentication을 실행한 결과 SecurityContextPersistenceFilter finally 스코프에서 session에 authentication 정보 또한 넣어 줍니다. 마지막으로 postman에서 basic authentication 후 발급 받은 쿠키만 있다면 이후 다음 요청에 authorization basic 헤더 필드가 없어도 인증된 결과를 확인할 수 있는데요. 제 생각에는 statefull과 stateless의 차이는 인증 방법(basic, form)이 아니라 http client의 차이인 것 같아요. 확인 부탁 드립니다. 감사합니다.
-
미해결실전! 웹사이트제작! Step By Step! _Basic (한화캐미컬_반응형웹)
완성 파일 main.css에 오타가 있습니다.
/*태블릿모드 786*/ @media screen and (max-widh: 786px){} 저 코드의 중괄호가 안닫혀 있어요.
-
미해결[백문이불여일타] 데이터 분석을 위한 중급 SQL
안녕하세요
중급반 가르쳐주시느라 고생 많으셨습니다ㅜ 수업 때 풀었던 문제들덕에 도움 많이 받았습니다 강의를 다 듣고 추가적으로 다른 문제들도 풀면서 익혀보고 싶은데 문제가 너무 많다보니 뭐가 좋은지 잘 모르겠네요.. 혹시 group by, case, join 등을 활용한 문제들을 더 뽑아주실수있나요?? 더 풀어보고싶네요
-
반응형 웹사이트 포트폴리오(Architecture Agency)
skillprogress 질문 드립니다!
삭제된 글입니다
-
해결됨Vue로 Nodebird SNS 만들기
제로초님 안녕하세요🙇♂️😄 nginx 설정과 관련된 질문드립니다.
제로초님 안녕하세요🙇♂️😄 nginx 설정과 관련된 질문드립니다. 일전에 하나의 EC2에 프론트와 백엔드를 배포하기 위해선 어떤 주의사항을 주실 수 있는지 여쭈었습니다. 😸제로초님께서 "각각의 주소와 포트를 어떻게 하실지 정하셨나요? 한 인스턴스에서 두 개의 서버를 돌리는 경우 nginx를 도입하시는 게 좋습니다." 와 같이 답변을 주셨습니다.👨🏫 그래서 제로초님 영상과 강의를 보면서 nginx를 통해 도메인 주소로 들어오는 요청 가령, 'https://ham.com'을 'http://127.0.0.1:3080' 으로 리버시 프록시하는 작업을 성공했습니다. 덕분에 도메인 주소로 접속할 경우 화면이 정상적으로 출력되는 부분까지는 완성을 했습니다. 그런데 한 단계 더 나아가고자 하니 약간의 어려움이 생겼습니다.😂😂 프론트와 백엔드는 같은 인스턴스 안에 있으니 axios에서 'http://127.0.0.1:3000(백엔드 주소)' 로 바로 요청을 보내면 되지 않을까 생각하여 특별한 설정없이, local 환경에서 작업한대로 진행했는데, cors 에러가 발생했습니다.🙄 그래서 강의 내용을 다시 돌아보니 6-9 도메인 연결하기 강의👨🏫에서 "반드시 도메인을 가지고 있어야지만 요청이 전송이 된다"고 말씀해주신 부분을 확인했습니다. 그래서 이 부분과 관련해 몇가지 질문드립니다.🙋♂️ 1. 그렇다면 백엔드 서버로 요청을 보내기 위한 프론트엔드 axios baseURL 설정 부분에도 백엔드의 IP 주소가 아니라 도메인 주소가 자리해야 하는 것인지 궁금합니다. 2. 혹시 지금 이 상황을 해결하려면 nginx에서 프론트엔드와 백엔드 양쪽으로 리버스 프록시를 해야 하는 걸까요? 3. 제가 막히고 있는 지점을 설명드리고 배움을 얻고자 하였는데, 혹시 제가 놓치고 있는 설정이나 부분이 있다면 혹시 말씀을 부탁드릴 수 있을까요? 감사합니다. 제로초님🙇♂️
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
models 최신 문법으로 변경 후
index 페이지에 /Posts 요청에서 sequelizeeagerloadingerror Image is not associated to Comment 에러가 나고 로그인도 안되요 models 폴더 말고 다른 파일도 수정해야하는 곳이 있나요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
중복 회원 검증 관련해서 질문드립니다.
안녕하세요, 우선 좋은 강의 만들어주셔서 감사합니다. 지난번 강의 때 만든 validateDuplicateMember 에서 중복된 이름을 가진 회원이면 IllegalStateException 에러를 던지도록 되어있는데, 이 부분에서 중복된 회원임을 알리고 다시 폼에서 요청받을 수 있도록 하려면 어떻게 해야하는지 궁금합니다. 현재는 whitelabel Error Page가 나오고, 로그에 "이미 존재하는 회원입니다."라는 메시지가 뜨더라구요..!
-
미해결리눅스 시스템 프로그래밍 - 이론과 실습
cur_cpu^1 이 잘 이해가 안됩니다!
^이 xor 아닌가요? 그러면 ^1을 하면 마지막 비트만 뒤집어지는건데 이게 혹시 cpu개수가 2개라서 가능한 건가요? 3개 이상이면 안되는거 맞나요? 마지막 비트로만 구분하는게 2개라서 가능한건지 궁금합니다!
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
react-images-gallery 사용이 이상합니다.
사진 크기도 들죽날쭉 하고 버튼도 빈칸으로 나옵니다. 제 코드가 문제가 있나 해서 github 코드 복사해도 같은 오류가 나옵니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
안녕하세요 강사님이 템플릿 엔진에 대해서 질문이 있습니다.
성능 문제로 템플릿 엔진보다는 웹 프레임워크 vue.js react.js angular.js를 쓴다고 들었습니다. 여기 강의에서 thymeleaf 템플릿 엔진을 사용했는데, spring에서 템플릿 엔진을 꼭 써야하는지 아니면 간단하게 예제로써만 사용하고 나중에는 react.js vue.js angular.js같은 웹 프레임워크를 사용하는 지 궁금합니다.
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
findByToken 에러 납니다 ㅠㅠ
함수가 아니라고 하는데 왜 그런걸까요?? TypeError: User.findByToken is not a function
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
안티패턴 관련 질문입니다.
아래 많은 분들이 질문 하셨던 그 내용인데요. "상위 컴포넌트에서 선언한 data는 하위 컴포넌트에서 변경하지 말아야한다"라는 의미는 알거같습니당 그럼 todoItem.completed = !todoItem.completed라는 소스에서 todoItem은 TodoList.vue에서 올려 보내준거라서 App.vue파일에서 수정하면 안좋다는 의미인가요? 이해가 잘 안됩니다..
-
미해결Vue.js 시작하기 - Age of Vue.js
promise,async await관련
강의도중 판교님이 올려주신 링크로들어가 3가지글을 읽었습니다. 비동기처리와 콜백함수는 바로이해가가지만 아직 웹초보라그런가, promise와 async,await는 막연히 이렇다라는것만 이해가가는데 이녀석들이 이렇다정도만 지금 알고있으면되는건가요? 판교님 vue.js모든강의 다 들을예정이긴합니다!
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
미들웨어질문
app.use(express.json()); app.use(express.urlencoded({extended: true})) 여기서 첫번째 express.json은 axios 요청이 올때 axios 두번째 인자의 데이터를 req.body에 넣는역할이고 두번째 express.urlencoded({extended:true})는 프론트에서 form을 통해 데이터가 날아오면 그 데이터들을 req.body에 넣는게 맞을까요 ? 그리고 extended:true라는 것은 어떤 옵션인가요 ?