묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Slack 클론 코딩[실시간 채팅 with React]
채널 생성시 404오류
안녕하세요!!! 강좌 열심히 따라하면서 배우는 중, 해결점을 찾을수 없는 부분이 있어서 질문합니다. *우선 리액트 v6를 사용하여 route가 아래와 같이 되었다는 것을 참고해주세요. **SWR역시 revalidate가 작동이 안되어, mutate사용하였습니다. [이슈사항] 채널 리스트는 잘 받아오는 것 같습니다. 하지만, 채널생성시 404에러가 발생합니다. 서버는 "존재하지 않는 워크스페이스입니다."라는 응답을 줍니다. 의심되는 것은 버전6 라우팅설정에 문제가 있지 않을까 생각되는데... 검색해봐도 딱히 잘못된것을 못 발견해서 이렇게 질문남깁니다. //CreateChannelModal 코드 import Modal from '@components/Modal';import React, { CSSProperties, useCallback, VFC } from 'react';import { Button, Input, Label } from '@pages/SignUp/styles';import useInput from '@hooks/useinput';import axios from 'axios';import { useParams } from 'react-router';import { toast } from 'react-toastify';import useSWR from 'swr';import { IChannel, IUser } from '@typings/db';import fetcher from '@utils/fetcher';interface Props { show: boolean; onCloseModal: () => void; setShowCreateChannelModal: (flag: boolean) => void;}const CreateChannelModal: VFC<Props> = ({ show, onCloseModal, setShowCreateChannelModal }) => { const [newChannel, onChangeNewChannel, setNewChannel] = useInput(''); const { workspace, channel } = useParams<{ workspace: string; channel: string }>(); const { data: userData, error, mutate } = useSWR<IUser | false>('http://localhost:3095/api/users', fetcher); const { data: channelData, mutate: mutateChannel } = useSWR<IChannel[]>( // 로그인하지 않은상태이면 호출안하고, null로 userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null, fetcher, ); const onCreateChannel = useCallback( (e) => { e.preventDefault(); axios .post( 'http://localhost:3095/api/workspaces/${workspace}/channels', { name: newChannel, }, { withCredentials: true, }, ) .then(() => { setShowCreateChannelModal(false); mutateChannel(); setNewChannel(''); }) .catch((error) => { console.dir(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [newChannel], ); return ( <Modal show={show} onCloseModal={onCloseModal}> <form onSubmit={onCreateChannel}> <Label id="channel-label"> <span>채널 이름</span> <Input id="channel" value={newChannel} onChange={onChangeNewChannel} /> </Label> <Button type="submit">생성하기</Button> </form> </Modal> );};export default CreateChannelModal; //Workspace 코드import React, { VFC, useCallback, useState } from 'react';import useSWR, { mutate } from 'swr';import fetcher from '@utils/fetcher';import axios from 'axios';import { Routes, Route, Navigate, Link } from 'react-router-dom';import { Header, LogOutButton, ProfileImg, ProfileModal, RightMenu, WorkspaceWrapper, Workspaces, Channels, Chats, WorkspaceName, MenuScroll, WorkspaceButton, AddButton, WorkspaceModal,} from '@layouts/Workspace/styles';import gravatar from 'gravatar';import loadable from '@loadable/component';import Menu from '@components/Menu';import { IChannel, IUser } from '@typings/db';import { Button, Input, Label } from '@pages/SignUp/styles';import useInput from '@hooks/useinput';import Modal from '@components/Modal';import CreateChannelModal from '@components/CreateChannelModal';import { toast } from 'react-toastify';import { useParams } from 'react-router';const Channel = loadable(() => import('@pages/Channel'));const DirectMessage = loadable(() => import('@pages/DirectMessage'));const Workspace: VFC = () => { const [showUserMenu, setShowUserMenu] = useState(false); const [showCreateWorkspaceModal, setShowCreateWorkspaceModal] = useState(false); const [showWorkspaceModal, setShowWorkspaceModal] = useState(false); const [showCreateChannelModal, setShowCreateChannelModal] = useState(false); const [newWorkspace, onChangeNewWorkspace, setNewWorkspace] = useInput(''); const [newUrl, onChangeNewUrl, setNewUrl] = useInput(''); const { workspace } = useParams<{ workspace: string }>(); const { data: userData, error, mutate } = useSWR<IUser | false>('http://localhost:3095/api/users', fetcher); const { data: channelData } = useSWR<IChannel[]>( // 로그인하지 않은상태이면 호출안하고, null로 userData ? `http://localhost:3095/api/workspaces/${workspace}/channels` : null, fetcher, ); const onLogout = useCallback((e) => { e.preventDefault(); axios .post('http://localhost:3095/api/users/logout', null, { withCredentials: true, }) .then((response) => { mutate(false, false); }); }, []); const onCloseUserProfile = useCallback((e) => { e.stopPropagation(); setShowUserMenu(false); }, []); const onClickUserProfile = useCallback(() => { setShowUserMenu((prev) => !prev); }, []); const onClickCreateWorkspace = useCallback(() => { setShowCreateWorkspaceModal(true); }, []); const onCreateWorkspace = useCallback( (e) => { e.preventDefault(); if (!newWorkspace || !newWorkspace.trim()) return; if (!newUrl || !newUrl.trim()) return; axios .post( 'http://localhost:3095/api/workspaces', { workspace: newWorkspace, url: newUrl, }, { withCredentials: true, }, ) .then((response) => { mutate(response.data); setShowCreateWorkspaceModal(false); setNewWorkspace(''); setNewUrl(''); }) .catch((error) => { console.dir(error); toast.error(error.response?.data, { position: 'bottom-center' }); }); }, [newWorkspace, newUrl], ); const onCloseModal = useCallback(() => { setShowCreateWorkspaceModal(false); setShowCreateChannelModal(false); }, []); const toggleWorkspaceModal = useCallback(() => { setShowWorkspaceModal((prev) => !prev); }, []); const onClickAddChannel = useCallback(() => { setShowCreateChannelModal(true); }, []); if (!userData) { return <Navigate replace to="/login" />; } return ( <div> <Header> <RightMenu> <span onClick={onClickUserProfile}> <ProfileImg src={gravatar.url(userData.email, { s: '28px', d: 'retro' })} alt={userData.email} /> {showUserMenu && ( <Menu style={{ right: 0, top: 38 }} show={showUserMenu} onCloseModal={onCloseUserProfile}> <ProfileModal> <img src={gravatar.url(userData.email, { s: '36px', d: 'retro' })} alt={userData.email} /> <div> <span id="profile-name">{userData.email}</span> <span id="profile-active">Active</span> </div> </ProfileModal> <LogOutButton onClick={onLogout}>로그아웃</LogOutButton> </Menu> )} </span> </RightMenu> </Header> <WorkspaceWrapper> <Workspaces> {userData?.Workspaces?.map((ws) => { return ( <Link key={ws.id} to={'/workspace/${123}/channel/일반'}> <WorkspaceButton>{ws.name.slice(0, 1).toUpperCase()}</WorkspaceButton> </Link> ); })} <AddButton onClick={onClickCreateWorkspace}>+</AddButton> </Workspaces> {/*<Workspaces>*/} {/* {userData?.Workspaces.map((ws) => {*/} {/* return (*/} {/* <Link key={ws.id} to={`/workspace/${123}/channel/일반`}>*/} {/* <WorkspaceButton>{ws.name.slice(0, 1).toUpperCase()}</WorkspaceButton>*/} {/* </Link>*/} {/* );*/} {/* })}*/} {/* <AddButton onClick={onClickCreateWorkspace}>+</AddButton>*/} {/*</Workspaces>*/} <Channels> <WorkspaceName onClick={toggleWorkspaceModal}>Sleact</WorkspaceName> <MenuScroll> <Menu show={showWorkspaceModal} onCloseModal={toggleWorkspaceModal} style={{ top: 95, left: 80 }}> <WorkspaceModal> <h2>Sleact</h2> {/*<button onClick={onClickInviteWorkspace}>워크스페이스에 사용자 초대</button>*/} <button onClick={onClickAddChannel}>채널 만들기</button> <button onClick={onLogout}>로그아웃</button> </WorkspaceModal> </Menu> {channelData?.map((v) => ( <div>{v.name}</div> ))} </MenuScroll> </Channels> <Chats> chats <Routes> <Route path="/channel/:channel" element={<Channel />} /> <Route path="/dm/:id" element={<DirectMessage />} /> </Routes> </Chats> </WorkspaceWrapper> <Modal show={showCreateWorkspaceModal} onCloseModal={onCloseModal}> <form onSubmit={onCreateWorkspace}> <Label id="workspace-label"> <span>워크스페이스 이름</span> <Input id="workspace" value={newWorkspace} onChange={onChangeNewWorkspace} /> </Label> <Label id="workspace-url-label"> <span>워크스페이스 url</span> <Input id="workspace" value={newUrl} onChange={onChangeNewUrl} /> </Label> <Button type="submit">생성하기</Button> </form> </Modal> <CreateChannelModal show={showCreateChannelModal} onCloseModal={onCloseModal} setShowCreateChannelModal={setShowCreateChannelModal} /> </div> );};export default Workspace; //App코드입니다import React from 'react';import loadable from '@loadable/component';import { Routes, Route, Navigate } from 'react-router-dom';const LogIn = loadable(() => import('@pages/LogIn'));const SignUp = loadable(() => import('@pages/SignUp'));const Workspace = loadable(() => import('@layouts/Workspace'));const App = () => { return ( <Routes> <Route path="/" element={<LogIn />} /> <Route path="/login" element={<LogIn />} /> <Route path="/signup" element={<SignUp />} /> <Route path="/workspace/:workspace/*" element={<Workspace />} /> </Routes> );};export default App;
-
미해결따라하며 배우는 리액트 테스트 [2023.11 업데이트]
테스트 실행시간
테스트 실행시간이 너무 긴것같아 질문남깁니다. 코드는 clone 후 npm i로 설치하여 개인적인 코드는 추가하지 않은 상태입니다. 강의에서는 Time이 1s 이내에 완료되는데 저는 4s가 넘어버리내요...
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
failed to sign up 해결이 안됩니다 ㅠㅠ
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'push') 페이지 콘솔창에서 확인해보니 이런 오류가 나있고 계속 failed to sign up이 뜹니다 다른분들의 답변에서도 해결책을 찾을 수 없어 도움 청합니다 ... 포스트맨 사용하니 register success가 나오는거 같은데,, 깃허브 주소 첨부합니다ㅠ https://github.com/aurpo1/boilerplate
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Validator 여러개
안녕하세요 강의 잘듣고 있습니다 validator를 global하게 적용할 때는 validator가 하나만 적용이되고 local에서 적용할때는 여러개를 등록할 수 있다고 생각 했는데 제 생각이 맞는지 궁금합니다! 추가적으로 local에 등록할 때 initBinder를 사용하여 add를 하는 부분이 있는데, 결국에는 이런식으로 초기화가 되어서 여러개(기본 global validator + 사용자 정의해서 등록해준 validator)의 validator를 가지게 되더라고요 그렇다면 Controller 매개변수에 있는 validator들에 적용 순위가 또한 존재하는 지 궁금합니다. 단순히 support로 구분하는지? 여기서 의심이 든 점이 global적용되는 validator가 정말 하나만 지원이 되는지 궁금합니다. 추가적으로 이런 궁금증으로 구글링 결과로 https://stackoverflow.com/questions/14533488/adding-multiple-validators-using-initbinder 내용을 보았는데 initBinder를 네이밍지어서 여러개의 binding을 할수 있다는 내용인데 해당 내용이 잘이해가지않아 추가 질문드립니다 감사합니다
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
1-I 1620번 문제 질문이 있습니다.
먼저 문제를 풀아보았는데, 자꾸 디버그 에러가 납니다. 예외 발생(0x00007FF63A1012C1, Baekjoon.exe): 0xC0000005: 0x00007FF63A1012C1 위치를 실행하는 동안 액세스 위반이 발생했습니다. 인터넷을 찾아 본 결과, 보통 위 디버그 에러는 1. 포인터에 값을 변경할 떄 2.할당 되지 않은 곳에 넣을 때 라고 했습니다. 근데 대체 그런 부분이 어디에 있는지 계속 고민을 해봐도 잘 모르겠습니다. 물론 올려주신 코드는 이해했습니다. 코드 지적 해주신다면 정말 감사하겠습니다 !!! #include <iostream> #include <map> #include <string> using namespace std; string name[100001]; map<string, int> Map; int input, cnt, a; int main() { cin >> input >> cnt; for (int i = 0; i < input; i++) { string s; cin >> s; name[i] = s; Map.insert({ s, i+1}); } for (int i = 0; i < cnt; i++) { string temp; cin >> temp; if (isdigit(temp[0]) == true) { a = stoi(temp); cout << name[a - 1] << endl; } else { auto iter = Map.find(temp); cout << iter->second << endl; } } }
-
미해결[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
BumbleBee 버전이신분 공유
잘되길래 공유해봅니다 android studio 상단 메뉴에서 Tools -> Firebase -> Realtime Database -> Get started with Realtime Database(둘중아무거나 누르셔도됩니다) -> (2) Add the Realtime Database SDK to your app -> Accept Changes 이러면 project , module gradle 둘다 코드 알아서 추가해주고 module 에서 implementation firbase-database:00.0.0 이부분 안쓰시면 지우셔도 되고 안지우셔도 됩니다 그 후에 module쪽 파이어베이스 문서에서 필요한 코드 복붙하면서 강의 쭉 따라가시면 됩니다
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
중복회원예외 부분 오류발생
[질문 내용] 다른 부분은 문제 없이 잘 진행했는데 해당 부분에서 에러가 발생하는데 이유를 모르겠습니다.. 혹시 어느 부분을 확인하면 될지 여쭤보고 싶어서 글 남깁니다! 항상 좋은 수업 쉽게 따라할 수 있도록 해주셔서 강의 열심히 보고 있습니다 감사합니다~
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
width와 height를 변경하였는데 적용되지 않아요.
강의 자료의 순서대로 width와 height를 300px로 변경하였는데 변하는 게 하나도 없습니다.(2분30초 부근내용) 개발자도구에 들어가면 변경된 내용은 적혀 있는데 화면에는 적용이 안되네요 어떻게 해야 문제가 해결될까요.ㅠ
-
해결됨예제로 공부하는 Java 100 문제풀이 Part.1
노트패드 주석 오류
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 수업을 따라서 프로그램을 작성하는데, 주석을 달면 자꾸 오류가 떠요. 원래 주석은 상관이 없는 것아닌가요? 강의 속 선생님은 주석을 달아도 아무렇지 않은데, 저는 주석 때문에 자꾸 오류가 나네요 주석을 지우고 하면 제대로 결과값이 도출되는데 주석만 넣으면 오류가 떠요. 왜 이러는 걸까요?
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
mutations
비동기 처리 로직을 선언하는 메서드. 비동기 로직을 담당하는 mutations 라고 되어있는데 mutations는 동기로직을 담당하는 곳이 아닌가요?
-
미해결홍정모의 따라하며 배우는 C언어
소수점 뒷부분 출력, %e로 출력
22:50 에서 콘솔창 3번째 줄에서 첫번째 칸 (123.456001)와 23:05에서 콘솔창 세번째 칸 (1.234560e+02)가 어떻게 나온것인지 모르겠습니다. 우선 첫번째는 float f = 123.456f; 를 %f로 출력한 것인데 이렇게 하면 123.456000도 아니고 왜 123.456001이 나오는지 모르겠습니다. 다음으로 3번째 칸에 1.234560e+02 가 출력된 것은 위의 float f = 123.456f; 를 %e로 출력한 것인데 +02가 뭘 뜻하는지 모르겠습니다. 1.234560에 10^2 를 곱하면 123.4560이 되는 것은 알겠는데 +02가 10^2를 의미하나요? +02는 배운적이 없었던 것 같은데 어떻게 이해하는것인지 모르겠습니다.
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
config 파일
config파일 다운로드할때 마지막에 raw=true 해주는 의미가 무엇인가요?
-
미해결모든 개발자를 위한 HTTP 웹 기본 지식
patch멱등성 관련 질문 2개입니다.
"PUT의 경우와 PATCH의 경우가 애매하긴 합니다만, PUT은 예를들면 AGE=30으로 계속 반복 호출하는 것이라고 생각하시면 됩니다. AGE에 30을 할당하는 행위는 몇번을 반복해도 항상 AGE가 30일 것입니다. PATCH는 반면에 AGE = AGE+1 이라고 생각하시면 됩니다. 이것은 호출될때마다 AGE의 값이 바뀌게 되겠죠. 그래서 PUT은 멱등, PATCH는 멱등하지 않다라고 합니다." 1. 위 글은 다른 분 질문에 달린 답변의 일부입니다. 여기서 이해가 되지 않는 점이 PUT은 AGE = 30처럼 덮어쓰는 행위라고 생각하면 된다고 하셨는데 PUT도 AGE = AGE+1로 반복적으로 덮어쓸 수 있는것 아닌가요? 이렇게 된다면 put도 계속 리소스가 변경되는 것 같은데 왜 멱등한 것인지 이해가 명확히 되지 않습니다. 2. 그리고 safe와 멱등의 차이점은 단순히 한 번 호출과 여러번 호출했을때의 차이점인 것인지 아니면 요청의 결과가 같다는것에 초점을 맞춰야할지 헷갈립니다... 여러번 호출해도 데이터가 변하지않는다는게 멱등인 것인지 아니면 요청의 의도가 계속 같다는 것이 멱등인것인지 궁금합니다.
-
해결됨PHP 7+ 프로그래밍: 객체지향
User 클래스에 대한 질문입니다.
안녕하세요, 강의를 보며 프로젝트 예제 코드를 따라 타이핑 하면서 궁금한 것이 있어 질문드립니다. 아마 '36-메인(Index)' 강의에서 Post 클래스를 사용함에 있어 생겼었떤 궁금증과 동일할 거 같습니다. '회원가입' 처리를 위해 UserController::store 정적 메소드에서 'POST' 방식으로 넘어온 'email', 'password' 데이터를 User 객체의 프로퍼티(멤버변수)로 설정하는 코드를 볼 수 있었습니다. 하지만 실제 User 클래스에서는 가령 public $email, public $password와 같이 프로퍼티(멤버변수)가 선언되어 있지 않았는데요. 이게 어떻게 가능하게 된건지 원리가 궁금합니다. P.S 저는 Java(SpringFramework)도 함께 공부를 진행중에 있습니다.(실무에서 Java, PHP 둘 다 쓰기에...) Java에서 클래스의 성질과 비슷하다라고 생각하니 이번 강의에서 보여주셨던 코드가 동작하는게 이해가 가지 않더라구요. 미리 답변 감사드립니다.
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
회원가입 시 sendgrid로 이메일 보내기 구현 중 질문드립니다.
강사님 안녕하세요~! 실습을 진행하면서 회원 가입시 sendgrid를 통해 메일을 보내는 부분 구현에서 에러 해결이 안되어 질문을 드립니다. 강의 영상을 참고해서, sendgrid 회원가입과, api key 발급을 마치고 다음과 같이 (window 환경에서 set 명령어를 통해) 환경 변수 설정이 된 것도 확인 했는데 회원가입 버튼을 누르면 다음과 같은 에러가 발생합니다. (django admin을 통해 봤을 때 회원가입은 이뤄지는 것을 보았습니다.) 혹시 에러의 원인이 무엇일지 짐작가시는 것이 있으실까 싶어서 질문을 드렸습니다. 그럼 감사합니다. !!
-
미해결
장고 프로젝트 중인데 페이지 이동이 되지를 않습니다.
파이썬과 장고를 이제 막 공부를 시작해서 프로젝트를 만들고 있는데, 아직 장고 기초지식이 부족한지 해결을 하기 어렵습니다.. 네이버 블로그 검색 api와 유튜브 api를 사용중이며, 구글처럼 메인페이지에서 검색을 하면, 그에 맞는네이버 블로그 글들과 유튜브 영상들이 나오게 하려고 합니다. 발생된 문제는, 검색 후 all.html 이라는 검색정보를 보여주는 페이지로 이동해야 되는데 왜인지 주소만 변경되고 이동이 되지않고 메인페이지로 유지됩니다. (http://127.0.0.1:8000/ -> http://127.0.0.1:8000/all ) <메인페이지> <코드> # urls.py from django.conf import settings from django.conf.urls import url, include from django.conf.urls.static import static from django.urls import path from . import views urlpatterns = [ url(r'^', views.index, name='index'), path('all/', views.all, name="all"), url(r'info/$', views.get_request_url, name="info"), url(r'video/$', views.youtube, name="video"), ] # views.py import json, os, sys, urllib.request, requests from django.shortcuts import render from django.conf import settings from django.views.generic import FormView from requests import request def index(request): return render(request, 'common/main.html') def make_naver_search_api_url(search_text, start_num, disp_num): base_url = 'https://openapi.naver.com/v1/search/blog.json' param_query = "?query=" + urllib.parse.quote(search_text) param_start = "&start=" + str(start_num) param_disp = "&display=" + str(disp_num) return base_url + param_query + param_start + param_disp def all(request): # naver search value search_text = request.POST.get('searchValue',"") API_URL = make_naver_search_api_url(search_text,1,30) config_secret_debug = json.loads(open(settings.SECRET_DEBUG_FILE).read()) client_id = config_secret_debug['NAVER']['CLIENT_ID'] client_secret = config_secret_debug['NAVER']['CLIENT_SECRET'] request = urllib.request.Request(API_URL) request.add_header("X-Naver-Client-Id", client_id) request.add_header("X-Naver-Client-Secret", client_secret) response = urllib.request.urlopen(request) rescode = response.getcode() print(rescode) if (rescode == 200): # youtube search value url = 'https://www.googleapis.com/youtube/v3/search' params = { 'key': '유튜브api', 'part': 'snippet', 'type': 'video', 'maxResults': '30', 'q': search_text, } response = requests.get(url, params) response_dict = response.json() response_body = response.read() naver_result = json.loads(response_body.decode('utf-8')) naver_items = naver_result.get('items') context = { 'items': naver_items, 'youtube_items': response_dict['items'] } return render(request, 'searchView/all.html', {'info_items': context[0], 'video_items': context[1]}) else: return None print("---error---") # main.html (메인페이지) <body> <div class="container"> <div class="mainBox"> <div class="logoBox"> <img src="{% static 'img/logo_transparent.png' %}" class="mainLogo"> </div> <form class="d-flex" method="POST" action="{% url 'all' %}"> {% csrf_token %} <div class="searchBox" style="display: flex"> <input class="form-control me-sm-2" type="text" placeholder="검색어를 입력" name="searchValue" value="{{ searchValue }}"> <button class="btn btn-info my-2 my-sm-0" type="submit">Search</button> </div> </form> </div> </div> </body> # all.html (페이지 이동 테스트 성공 후 작업예정) - 이 페이지는 무시하셔도 됩니다 {% extends 'common/base.html' %} {% block content %} <div class="contentFlexBox"> <div class="infoBox"> <div class="infoDetail"> {% for info in info_items %} <a href="{{ info.link }}" class="list-group-item list-group-item-action flex-column align-items-start"> <div class="d-flex w-100 justify-content-between"> <h5 class="mb-1">{{ info.title }}</h5> <small class="text-muted">{{ info.bloggername }}</small> </div> <p class="mb-1">{{ info.description }}</p> <small class="text-muted">{{ info.postdate | date:"Y-m-d"}}</small> </a> {% endfor %} </div> <div class="pageNavi"> <ul class="pagination"> <li class="page-item disabled"> <a class="page-link" href="#">«</a> </li> <li class="page-item active"> <a class="page-link" href="#">1</a> </li> <li class="page-item"> <a class="page-link" href="#">2</a> </li> <li class="page-item"> <a class="page-link" href="#">3</a> </li> <li class="page-item"> <a class="page-link" href="#">4</a> </li> <li class="page-item"> <a class="page-link" href="#">5</a> </li> <li class="page-item"> <a class="page-link" href="#">»</a> </li> </ul> </div> </div> <div class="videoBox"> <a href="#" style="text-decoration: none;"> <div class="card mb-3"> <div class="card-body videoText"> <h5 class="card-title">영상제목</h5> <h6 class="card-subtitle text-muted">채널주인</h6> </div> <svg xmlns="http://www.w3.org/2000/svg" class="d-block user-select-none" width="100%" height="200" aria-label="Placeholder: video cap" focusable="false" role="img" preserveAspectRatio="xMidYMid slice" viewBox="0 0 318 180" style="font-size:1.125rem;text-anchor:middle"> <rect width="100%" height="100%" fill="#868e96"></rect> <text x="50%" y="50%" fill="#dee2e6" dy=".3em">video cap</text> </svg> <div class="card-body videoText"> <p class="card-text">동영상 소개글</p> </div> <div class="card-footer text-muted"> 게시일 </div> </div> </a> <div class="pageNavi"> <ul class="pagination"> <li class="page-item disabled"> <a class="page-link" href="#">«</a> </li> <li class="page-item active"> <a class="page-link" href="#">1</a> </li> <li class="page-item"> <a class="page-link" href="#">2</a> </li> <li class="page-item"> <a class="page-link" href="#">3</a> </li> <li class="page-item"> <a class="page-link" href="#">4</a> </li> <li class="page-item"> <a class="page-link" href="#">5</a> </li> <li class="page-item"> <a class="page-link" href="#">»</a> </li> </ul> </div> </div> </div> {% endblock %} 책도 보고 인터넷을 검색해도 도통 해결방법을 모르겠습니다.. 혹시 어디부분이 문제인지 말씀해주시면 확인 후 수정하겠습니다..!
-
해결됨PHP 7+ 프로그래밍: 객체지향
password_verify(string, hash) 함수가 매번 false가 나오는 것에 대한 해결 방법이 궁금합니다.
안녕하세요, 프로젝트 '인증' 파트에서 로그인 시 입력하게 되는 이메일과 비밀번호를 AuthController, AuthService를 통해 처리하는 것을 확인 할 수 있었습니다. 저는 현재 PHP 8.0.0 버전으로 코딩을 진행하고 있습니다. 다만, AuthService::login 로직에서 password_verify(string, hash)가 항상 false로 결과 값이 반환되는 것을 확인했습니다. 처음에는 예제 코드를 타이핑하는데 오탈자가 있었나 확인해 보았지만 그런 경우는 없었습니다. 이와 동일한 이슈에 대해 찾아보았으나 여러 개 있었고, 그 중 PHP 8 환경에서의 이슈를 다룬 블로그를 발견했습니다. (https://blog.naver.com/PostView.nhn?blogId=gwi01304&logNo=222269515571) PHP 버전 업데이트가 되면서 해당 함수의 동작 방식이 달라진 것인지 알 수 있을까요? 혹시 몰라서 저의 깃헙 레포지토리 URL을 여기에 공유해 드리겠습니다. GitHub URL: https://github.com/painkill2r/php-oop-project ============================================= 추가적으로 password_verify(string, hash) 함수의 동작 원리에 대해 궁금합니다. PHP Manual에서도 내부 동작 원리가 어떻게 되는지는 기재되어 있지 않더라구요. 첫 번째 인자로 주어진 string 값을 내부적으로 password_hash() 함로 암호화(?)하고, 이를 두 번째 인자와 비교하는게 맞을까요?
-
해결됨
h2 데이터베이스 실행시 오류가납니다 ㅠㅠ
The Web Console server could not be started. Possible cause: another server is already running at http://localhost:8082?key=4f0a1d21bf2d0c0a1743f6c247af3395cb3bba08ff6d6ec8db9432df4e709cd1 Root cause: Exception opening port "8082" (port may be in use), cause: "java.net.BindException: Address already in use (Bind failed)" [90061-200] Exception in thread "main" org.h2.jdbc.JdbcSQLNonTransientConnectionException: Exception opening port "8082" (port may be in use), cause: "java.net.BindException: Address already in use (Bind failed)" [90061-200] at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) at org.h2.message.DbException.get(DbException.java:194) at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:180) at org.h2.util.NetUtils.createServerSocket(NetUtils.java:146) at org.h2.server.web.WebServer.start(WebServer.java:389) at org.h2.tools.Server.start(Server.java:511) at org.h2.tools.Console.runTool(Console.java:208) at org.h2.tools.Console.main(Console.java:72) Caused by: java.net.BindException: Address already in use (Bind failed) at java.base/java.net.PlainSocketImpl.socketBind(Native Method) at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:452) at java.base/java.net.ServerSocket.bind(ServerSocket.java:381) at java.base/java.net.ServerSocket.<init>(ServerSocket.java:243) at java.base/java.net.ServerSocket.<init>(ServerSocket.java:135) at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:176) ... 5 more 이렇게 오류가 나는데... 강사님이 이전 질문에 답변에서 java -cp h2-1.4.200.jar org.h2.tools.Server -webPort 8083 를 적어주면 해결된다고 하셨었습니다. 근데 mac에서도 이렇게 입력하니까 일단 실행은됩니다만.. 근본적인 해결책인지가 궁금합니다. 저렇게 실행하고 나서.. ./h2.sh를 하게되면 똑같이 실행이 안되거든요 ㅠㅠ 혹시 다른 해결책이 있나요... port번호를 바꾸고싶은데 어떻게하는지도 잘 모르겠습니다.ㅠㅠ
-
미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
강사님 세션쿠키에대해
제가 스프링 으로 톰켓환경 세션이 생기면 JSESSIONID 쿠키가 생겼는데 노드에서는 CONNECT.SID 가 저것에 대응되는건가요? 이런건 런타임별로 자기들이 개발할떄 저런명으로 세션쿠키의 명을 정해놓은건가요?
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
Model → Store
Flux소개할 때 세번째 단계가 model에서 마지막에 Store로 바뀌는데왜 이렇게 되는지 의문입니다.