커뮤니티
포인트
쿠폰
내 강의실
국비 신청 내역
증명서
계정
로그아웃
학습 질문
개발 일지
나의 활동
답변 완료
잘 되던 GET 함수가 아무것도 변경하지 않았는데 갑자기 되지 않습니다ㅠㅠ
undefined주차
북마크
장*서
댓글
4
추천
0
조회수
20
조회수
20
답변 완료


잘 되던 GET 함수가 아무것도 변경하지 않았는데 갑자기 되지 않습니다ㅠㅠ 

DB에 저장도 잘 되고, get 함수 get_posts도 잘 되다가 어느순간 갑자기 작동을 하지 않습니다.



보고 계신 화면 전체를 캡처해 주시면, 튜터님들이 빠르게 상황을 상황을 이해할 수 있어요.

스파르타 즉문즉답스파르타 즉문즉답

저 카드 자리에 원래 db에 들어가있는 내용들이 들어가야 하는데 정상적으로 작동이 안됩니다.

스파르타 즉문즉답


콘솔창에도 찍히는 내용은 없습니다ㅜㅜ


작성한 코드 및 에러 메세지

  1. index.html
<!DOCTYPE html>
<html lang="en">

<head>

    <title>Cookping</title>

    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bulma CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">


    <!-- JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>

    <!--my CSS-->
    <link href="{{ url_for('static', filename='mystyle.css') }}" rel="stylesheet">

    <script>

        // const getButton = document.querySelector("#getBtn");
        // const youtubeUrl = document.querySelectorAll(".youtube-url");
        // const thumbnailWrap = document.querySelector(".thumbnail-wrap");
        // getButton.addEventListener('click', getThum);
        const inputUrl = document.querySelector('.field input');
        let preview = document.querySelector('.preview');

        // let thumb = preview.querySelector('.thumb')

        function post() {
            let title = $("#title").val();
            let comment = $("#comment").val();
            let today = new Date().toISOString();
            let form_data = new FormData();
            let url = $("#url").val();
            // preview.classList.add('current')

            // https://www.youtube.com/watch?v=Xwlsq_-fmrg
            // https://youtu.be/Xwlsq_-fmrg
            // https://youtube.com/watch?v=Xwlsq_-fmrg
            // https://www.youtu.be/Xwlsq_-fmrg

            const pattern1 = 'https://www.youtube.com/watch?v='
            const pattern2 = 'https://youtube.com/watch?v='
            const pattern3 = 'https://youtu.be/'
            const pattern4 = 'https://www.youtu.be/'

            if (url.indexOf(pattern1) != -1 || url.indexOf(pattern2) != -1) {
                let valid = url.split('watch?v=')[1].substring(0, 11);
                var imageThumb = `https://img.youtube.com/vi/${valid}/hqdefault.jpg`
                imageThumb
            } else if (url.indexOf(pattern3) != -1 || url.indexOf(pattern4) != -1) {
                let valid = url.split('be/')[1].substring(0, 11);
                var imageThumb = `https://img.youtube.com/vi/${valid}/hqdefault.jpg`

            } else {
                imageThumb = ""
                // preview.classList.remove('current')
            }

            form_data.append("title_give", title)
            form_data.append("comment_give", comment)
            form_data.append("url_give", url)
            form_data.append("img_give", imageThumb)
            form_data.append("date_give", today)

            $.ajax({
                type: "POST",
                url: "/posting",
                data: form_data,
                cache: false,
                contentType: false,
                processData: false,
                success: function (response) {
                    $("#modal-post").removeClass("is-active")
                    window.location.reload()
                }
            })
        }

        function time2str(date) {
            let today = new Date()
            let time = (today - date) / 1000 / 60  // 분

            if (time < 60) {
                return parseInt(time) + "분 전"
            }
            time = time / 60  // 시간
            if (time < 24) {
                return parseInt(time) + "시간 전"
            }
            time = time / 24
            if (time < 7) {
                return parseInt(time) + "일 전"
            }
            return `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}일`
        }

        function get_posts() {
            $("#post-box").empty()
            $.ajax({
                type: "GET",
                url: "/get_posts",
                data: {},
                success: function (response) {
                    if (response["result"] == "success") {
                        let posts = response["posts"]
                        for (let i = 0; i < posts.length; i++) {
                            let post = posts[i]
                            let time_post = new Date(post["date"])
                            let time_before = time2str(time_post)
                            let html_temp = `<div class="container" id="${post["_id"]}">
                                                <div class="card-image">
                                                     <figure class="image is-4by3">
                                                        <img src="${post['img']}" alt="Placeholder image">
                                                    </figure>
                                                </div>
                                                <div class="card-content">
                                                    <div class="media">
                                                        <div class="media-left">
                                                            <figure class="image is-48x48" href="/user/${post['username']}">
                                                                 <img  src="/static/${post['profile_pic_real']}" alt="Image">
                                                            </figure>
                                                        </div>
                                                <div class="media-content">
                                                    <p class="title is-4">${post['title']}</p>
                                                    <p class="subtitle is-6">${post['profile_name']}</p>
                                                </div>
                                                </div>

                                                <div class="content">
                                                    ${post['comment']}
                                                    <br>
                                                    <a href="${post['url']}">YOUTUBE</a>
                                                    <br>
                                                    <time datetime="2016-1-1">${time_before}</time>
                                                </div>
                                                    <nav class="level is-mobile">
                                                    <div class="level-left">
                                                        <a class="level-item is-sparta" aria-label="heart" onclick="toggle_like('${post['_id']}', 'heart')">
                                                            <span class="icon is-small"><i class="fa fa-heart"
                                                                                           aria-hidden="true"></i></span>&nbsp;<span class="like-num">2.7k</span>
                                                        </a>
                                                    </div>

                                                </nav>
            </div>
        </div>`
                            $("#post-box").append(html_temp)
                        }
                    }
                }
            })
        }

        $(document).ready(function () {
            get_posts()
        })


        // 로그아웃은 내가 가지고 있는 토큰만 쿠키에서 없애면 됩니다.
        function logout() {
            $.removeCookie('mytoken');
            alert('로그아웃!')
            window.location.href = '/login'
        }


    </script>

    <!-- Favicon -->
    <link href="../static/images/favicon.ico" rel="icon">

    <!-- Google Web Fonts -->
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">

    <!-- Font Awesome -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.0/css/all.min.css" rel="stylesheet">

    <!-- Libraries Stylesheet -->
    <link href="../static/lib/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet">
    <link href="../static/lib/tempusdominus/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet"/>

    <!-- Customized Bootstrap Stylesheet -->
    <link href="../static/css/style2.css" rel="stylesheet">
</head>

<body>
<!-- Topbar Start -->
<div class="container-fluid bg-light pt-3 d-none d-lg-block">
    <div class="container">
        <div class="row">
            <div class="col-lg-6 text-center text-lg-left mb-2 mb-lg-0">
                <div class="d-inline-flex align-items-center">
                    <!--<p><i class="fa fa-envelope mr-2"></i>info@example.com</p>
                    <p class="text-body px-3">|</p>
                    <p><i class="fa fa-phone-alt mr-2"></i>+012 345 6789</p> -->
                </div>
            </div>
            <div class="col-lg-6 text-center text-lg-right">
                <div class="d-inline-flex align-items-center">


                </div>
            </div>
        </div>
    </div>
</div>
<!-- Topbar End -->


<!-- Navbar Start -->
<div class="container-fluid position-relative nav-bar p-0">
    <div class="container-lg position-relative p-0 px-lg-3" style="z-index: 9;">
        <nav class="navbar navbar-expand-lg bg-light navbar-light shadow-lg py-3 py-lg-0 pl-3 pl-lg-5">
            <a href="/"><img src="../static/images/cookpinglogo1.png" alt="로고이미지" width="200px"></a>
            <!-- <a href="" class="navbar-brand">
                <h1 class="m-0 text-primary">cookping</h1>
            </a> -->
            <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse justify-content-between px-3" id="navbarCollapse">
                <div class="navbar-nav ml-auto py-0">
                    <a href="/" class="nav-item nav-link active">쿡핑레시피</a>
                    <a href="/about" class="nav-item nav-link">쿡핑이란?</a>
                    <a href="javascript:logout();" class="nav-item nav-link">로그아웃</a>
                </div>
            </div>
        </nav>
    </div>
</div>
<!-- Navbar End -->


<!-- Header Start -->
<div class="container-fluid page-header">
    <div class="container">
        <div class="d-flex flex-column align-items-center justify-content-center" style="min-height: 400px">
            <h3 class="display-4 text-white text-uppercase">Cookping Recipe</h3>
            <div class="d-inline-flex text-white">
                <p class="m-0 text-uppercase">캠핑요리 레시피를 공유해 보아요</p>
            </div>
        </div>
    </div>
</div>
<!-- Header End -->


<section class="section">
    <article class="media">
        <figure class="media-left" style="align-self: center">
            <a class="image is-32x32" href="/user/{{ user_info.username }}">
                <img class="is-rounded" src="{{ url_for('static', filename=user_info.profile_pic_real) }}">
            </a>
        </figure>
        <div class="media-content">
            <div class="field">
                <p class="control">
                    <input id="input-post" class="input is-rounded" placeholder="Youtube Link 공유하기"
                           onclick='$("#modal-post").addClass("is-active")'></p>
            </div>
        </div>
    </article>
    <div class="modal" id="modal-post">
        <div class="modal-background" onclick='$("#modal-post").removeClass("is-active")'></div>
        <div class="modal-content">
            <div class="box">
                <article class="media">
                    <div class="media-content">
                        <div class="field">
                            <p class="control">
                                <input class="input is-normal" id="title" type="text"
                                       placeholder="글 제목">

                                <textarea class="textarea" id="comment" placeholder="코멘트"></textarea>

                                <input class="input is-normal" id="url" type="text" placeholder="URL">
                            </p>
                        </div>
                        <nav class="level is-mobile">
                            <div class="level-left">
                            </div>
                            <div class="level-right">
                                <div class="level-item">
                                    <a class="button is-sparta" onclick="post()">작성</a>
                                </div>
                                <div class="level-item">
                                    <a class="button is-sparta is-outlined"
                                       onclick='$("#modal-post").removeClass("is-active")'>취소</a>
                                </div>
                            </div>
                        </nav>
                    </div>
                </article>
            </div>
        </div>
        <button class="modal-close is-large" aria-label="close"
                onclick='$("#modal-post").removeClass("is-active")'></button>
    </div>
</section>

<section class="section">
   <div class="container">
      <div class="card">
         <div class="card-image">
            <figure class="image is-4by3">
               <img src="https://bulma.io/images/placeholders/1280x960.png" alt="Placeholder image">
            </figure>
         </div>
         <div class="card-content">
            <div class="media">
               <div class="media-left">
                  <figure class="image is-48x48">
                     <img src="https://bulma.io/images/placeholders/96x96.png" alt="Placeholder image">
                  </figure>
               </div>
               <div class="media-content">
                  <p class="title is-4">John Smith</p>
                  <p class="subtitle is-6">@johnsmith</p>
               </div>
            </div>

            <div class="content">
               Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec iaculis mauris. <a>@bulmaio</a>.
               <a href="#">#css</a> <a href="#">#responsive</a>
               <br>
               <time datetime="2016-1-1">11:09 PM - 1 Jan 2016</time>
            </div>
         </div>
      </div>

   </div>

</section>



<!-- Footer Start -->
<div class="container-fluid bg-dark text-white-50 py-5 px-sm-3 px-lg-5" style="margin-top: 90px;">
    <div class="row pt-5">
        <div class="col-lg-3 col-md-6 mb-5">
            <a href="" class="navbar-brand">
                <a href="/"><img src="../static/images\cookpinglogo2.png" alt="로고이미지" width="200px"></a>
            </a>
            <p>요즘엔 캠핑이 대세!🔥 <br> 캠핑가서 굽는 요리만 하기는 질렸다!😐😐<br>
                캠핑, 여행, 펜션가서 할 수 있는 다양한 요리 레시피를 추천하고 공유하는 사이트입니다. 🍽</p>
        </div>
        <div class="col-lg-3 col-md-6 mb-5">
            <h5 class="text-white text-uppercase mb-4" style="letter-spacing: 5px;">Cookping Recipe</h5>
            <div class="d-flex flex-column justify-content-start">
                <a class="text-white-50 mb-2" href="/"><i class="fa fa-angle-right mr-2"></i>쿡핑레시피</a>
            </div>
        </div>
        <div class="col-lg-3 col-md-6 mb-5">
            <h5 class="text-white text-uppercase mb-4" style="letter-spacing: 5px;">About us</h5>
            <div class="d-flex flex-column justify-content-start">
                <a class="text-white-50 mb-2" href="/about"><i class="fa fa-angle-right mr-2"></i>쿡핑이란?</a>
            </div>
        </div>
        <div class="col-lg-3 col-md-6 mb-5">
            <h5 class="text-white text-uppercase mb-4" style="letter-spacing: 5px;">Our Project
                Info</h5>
            <div class="d-flex flex-column justify-content-start">
                <a class="text-white-50 mb-2" href="https://hightechsoon.tistory.com/15"><i
                        class="fa fa-angle-right mr-2"></i>Starting Assignment</a>
                <a class="text-white-50 mb-2" href="https://github.com/Younddo/campinggabojago"><i
                        class="fa fa-angle-right mr-2"></i>Github</a>
                <a class="text-white-50 mb-2" href="https://discord.gg/krQhXcZXmG"><i
                        class="fa fa-angle-right mr-2"></i>Discord</a>

            </div>

        </div>
    </div>
</div>
<div class="container-fluid bg-dark text-white border-top py-4 px-sm-3 px-md-5"
     style="border-color: rgba(256, 256, 256, .1) !important;">
    <div class="row">
        <div class="col-lg-6 text-center text-md-left mb-3 mb-md-0">
            <p class="m-0 text-white-50">Copyright &copy; <a href="#">항해99 9기 11조 풀스택미니프로젝트</a>. All
                Rights
                Reserved.</a>
            </p>
        </div>

        <div class="col-lg-6 text-center text-md-right">
            <p class="m-0 text-white-50">Designed by <a href="https://htmlcodex.com">HTML Codex</a>
            </p>
        </div>

    </div>
</div>
<!-- Footer End -->


<!-- Back to Top -->
<a href="#" class="btn btn-lg btn-primary btn-lg-square back-to-top"><i
        class="fa fa-angle-double-up"></i></a>


<!-- JavaScript Libraries -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js"></script>
<script src="../static/lib/easing/easing.min.js"></script>
<script src="../static/lib/owlcarousel/owl.carousel.min.js"></script>
<script src="../static/lib/tempusdominus/js/moment.min.js"></script>
<script src="../static/lib/tempusdominus/js/moment-timezone.min.js"></script>
<script src="../static/lib/tempusdominus/js/tempusdominus-bootstrap-4.min.js"></script>

<!-- Contact Javascript File -->
<script src="../static/mail/jqBootstrapValidation.min.js"></script>
<script src="../static/mail/contact.js"></script>

<!-- Template Javascript -->
<script src="../static/js/main2.js"></script>
</body>

</html>

2.app.py

from flask import Flask, render_template, jsonify, request, session, redirect, url_for
import jwt
import datetime
from datetime import datetime, timedelta
import hashlib
from werkzeug.utils import secure_filename
from pymongo import MongoClient

import certifi
app = Flask(__name__)
ca = certifi.where()
client = MongoClient('mongodb+srv://test:sparta@cluster0.jetf0d5.mongodb.net/Cluster0?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta_cookping

# JWT 토큰을 만들 때 필요한 비밀문자열입니다. 아무거나 입력해도 괜찮습니다.
# 이 문자열은 서버만 알고있기 때문에, 내 서버에서만 토큰을 인코딩(=만들기)/디코딩(=풀기) 할 수 있습니다.
SECRET_KEY = 'SPARTA'




#################################
##  HTML을 주는 부분             ##
#################################
@app.route('/')
def home():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        user_info = db.users.find_one({"username": payload["id"]})
        return render_template('index.html', user_info=user_info)
    except jwt.ExpiredSignatureError:
        return redirect(url_for("login", msg="로그인 시간이 만료되었습니다."))
    except jwt.exceptions.DecodeError:
        return redirect(url_for("login", msg="로그인 정보가 존재하지 않습니다."))


@app.route('/login')
def login():
    msg = request.args.get("msg")
    return render_template('login.html', msg=msg)

@app.route('/about')
def about():
    msg = request.args.get("msg")
    return render_template('about.html', msg=msg)


@app.route('/user/<username>')
def user(username):
    # 각 사용자의 프로필과 글을 모아볼 수 있는 공간
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        status = (username == payload["id"])  # 내 프로필이면 True, 다른 사람 프로필 페이지면 False

        user_info = db.users.find_one({"username": username}, {"_id": False})
        return render_template('user.html', user_info=user_info, status=status)
    except (jwt.ExpiredSignatureError, jwt.exceptions.DecodeError):
        return redirect(url_for("home"))


@app.route('/sign_in', methods=['POST'])
def sign_in():
    # 로그인
    username_receive = request.form['username_give']
    password_receive = request.form['password_give']

    pw_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
    result = db.users.find_one({'username': username_receive, 'password': pw_hash})

    if result is not None:
        payload = {
         'id': username_receive,
         'exp': datetime.utcnow() + timedelta(seconds=60)  # 로그인 60s유지
        }
        token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

        return jsonify({'result': 'success', 'token': token})
    # 찾지 못하면
    else:
        return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})


@app.route('/sign_up/save', methods=['POST'])
def sign_up():
    username_receive = request.form['username_give']
    password_receive = request.form['password_give']
    password_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
    doc = {
        "username": username_receive,                               # 아이디
        "password": password_hash,                                  # 비밀번호
        "profile_name": username_receive,                           # 프로필 이름 기본값은 아이디
        "profile_pic": "",                                          # 프로필 사진 파일 이름
        "profile_pic_real": "profile_pics/profile_placeholder.png", # 프로필 사진 기본 이미지
        "profile_info": ""                                          # 프로필 한 마디
    }
    db.users.insert_one(doc)
    return jsonify({'result': 'success'})


@app.route('/sign_up/check_dup', methods=['POST'])
def check_dup():
    username_receive = request.form['username_give']
    exists = bool(db.users.find_one({"username": username_receive}))
    return jsonify({'result': 'success', 'exists': exists})


@app.route('/update_profile', methods=['POST'])
def save_img():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        # 프로필 업데이트
        return jsonify({"result": "success", 'msg': '프로필을 업데이트했습니다.'})
    except (jwt.ExpiredSignatureError, jwt.exceptions.DecodeError):
        return redirect(url_for("home"))


@app.route('/posting', methods=['POST'])
def posting():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        user_info = db.users.find_one({"username": payload["id"]})

        # file = request.files["file_give"]
        # extension = file.filename.split('.')[1]
        #
        # today = datetime.now()
        # mytime = today.strftime('%Y-%m-%d-%H-%M-%S')
        #
        # filename = f'file-{mytime}'
        # save_to = f'static/{filename}.{extension}'
        # file.save(save_to)

        title_receive = request.form["title_give"]
        comment_receive = request.form["comment_give"]
        url_receive = request.form["url_give"]
        img_receive = request.form["img_give"]
        date_receive = request.form["date_give"]
        doc = {
            "username": user_info["username"],
            "profile_name": user_info["profile_name"],
            "profile_pic_real": user_info["profile_pic_real"],
            "title":title_receive,
            "comment": comment_receive,
            "url":url_receive,
            "img":img_receive,
            "date": date_receive
        }
        db.posts.insert_one(doc)
        return jsonify({"result": "success", 'msg': '포스팅 성공'})
    except (jwt.ExpiredSignatureError, jwt.exceptions.DecodeError):
        return redirect(url_for("home"))


@app.route("/get_posts", methods=['GET'])
def get_posts():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        posts = list(db.posts.find({}).sort("date", -1).limit(20))
        for post in posts:
            post["_id"] = str(post["_id"])
        return jsonify({"result": "success", "msg": "포스팅을 가져왔습니다.","posts":posts})
    except (jwt.ExpiredSignatureError, jwt.exceptions.DecodeError):
        return redirect(url_for("home"))


@app.route('/update_like', methods=['POST'])
def update_like():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        # 좋아요 수 변경
        return jsonify({"result": "success", 'msg': 'updated'})
    except (jwt.ExpiredSignatureError, jwt.exceptions.DecodeError):
        return redirect(url_for("home"))


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)


취소
 공유
취소
댓글 0
댓글 알림
나의얼굴