Skip to content

JavaScript ajax

egoing edited this page Nov 16, 2021 · 10 revisions

Ajax + Restful API 예제

설정 방법

아래와 같이 파일을 위치합니다. 
/app.py
/templates/index.html

플라스크를 설치합니다. 
pip3 install flask

실행합니다. 
python3 app.py

http://localhost:5000/ 으로 접속했을 때 CRUD 기능을 갖춘 웹애플리케이션이 뜨면 됩니다. 

python3 예제 - app.py

import random
from flask import Flask, request, redirect, send_from_directory, render_template, make_response, make_response, Response
import json
from flask_cors import CORS


import sqlite3
app = Flask(__name__)
CORS(app)

resp = Response()
resp.headers['Access-Control-Allow-Origin'] = '*'


@app.route('/topics', defaults={'topic_id':None}, methods=['GET', 'POST'])
@app.route('/topics/<topic_id>', methods=['PUT', 'GET', 'DELETE'])
def topics(topic_id):
    try:
        db = sqlite3.connect('topics.db')
        db.row_factory = sqlite3.Row
        cursor = db.cursor()
        cursor.execute("SELECT count(name) FROM sqlite_master WHERE type='table' AND name='topic'")
        if cursor.fetchone()[0] == 1:
            print('Table exist')
        else:
            sql = """
                CREATE TABLE "topic" (
                    "id"	INTEGER,
                    "title"	TEXT,
                    "body"	TEXT,
                    PRIMARY KEY("id" AUTOINCREMENT)
                )
            """
            cursor.execute(sql)
            db.commit()
        
        if request.method == 'GET':
            if topic_id == None:
                sql = "SELECT * FROM topic"
                cursor.execute(sql)
                topics = cursor.fetchall()
                output = []
                for topic in topics:
                    output.append({'id':topic['id'], 'title':topic['title'], 'body':topic['body']})
                resp.set_data(json.dumps(output))
                return resp
            else:
                sql = "SELECT * FROM topic WHERE id = "+str(topic_id)
                cursor.execute(sql)
                topic = cursor.fetchone()                
                output = json.dumps({'id':topic['id'], 'title':topic['title'], 'body':topic['body']})
                resp.set_data(output)
                return resp
        elif request.method == 'POST':
            form = request.get_json()
            sql = """
                INSERT INTO topic (title, body) 
                VALUES(
                    '%(title)s',
                    '%(body)s'
                )
                """ % {'title':form['title'], 'body':form['body']}
            cursor.execute(sql)
            db.commit()
            output = json.dumps({'id':cursor.lastrowid, 'title':form['title'], 'body':form['body'] })
            resp.set_data(output)
            return resp
        elif request.method == 'PUT':
            form = request.get_json()
            sql = """
                UPDATE topic SET 
                    title = '%(title)s', 
                    body = '%(body)s'
                WHERE id = '%(topic_id)s'
                """ % {'topic_id': topic_id, 'title':form['title'], 'body':form['body']}
            cursor.execute(sql)
            db.commit()
            output = json.dumps({'id':topic_id, 'title':form['title'], 'body':form['body'] })
            resp.set_data(output)
            return resp
        elif request.method == 'DELETE':
            sql = """
                DELETE FROM topic WHERE id = %(id)s            
                """ % {'id':topic_id}
            cursor.execute(sql)
            db.commit()
            output = json.dumps({'id':topic_id})
            resp.set_data(output)
            return resp
    except Exception as e:
        print('error', e)
    finally:
        cursor.close()
        db.close()



@app.route('/static/<path:path>')
def static_files(path):
    return send_from_directory('static', path)

@app.route('/', defaults={'path':None})
@app.route('/<path>')
def index(path):
    resp.set_data(render_template('index.html'))    
    return resp

if __name__ == '__main__':
	app.run(debug=True)

html+javascript 예제 - index.html

<html>
    <body>
        <h1><a href="/" onclick="
            event.preventDefault();
            nav();
            welcome();    
            history.pushState({}, 'Welcome', '/');
        ">WEB</a></h1>
        <ul>
            
        </ul>
        <article>
            
        </article>
        <ul id="control">
            
        </ul>
        <script>
            selected_id = null;
            function control(){
                var selected_control = '';
                if(selected_id){
                    selected_control = `
                        <li>
                            <input type="button" value="update" onclick="update();">
                        </li>
                        <li>
                            <input type="button" value="delete" onclick="delHandler();">
                        </li>
                    `;
                }                
                document.querySelector('#control').innerHTML = `
                <li>
                    <input type="button" value="create" onclick="create()">
                    ${selected_control}
                </li>
                
                `
            }
            function topicClickHandler(topic_id){
                event.preventDefault();
                topic(topic_id);
                control();
                history.pushState({}, 'topic', '/'+topic_id);
            }

            function nav(){
                fetch('/topics')
                .then(function(type){
                    return type.json();
                })
                .then(function(result){
                    var str = '';
                    for(var i=0; i<result.length; i++){
                        var r = result[i];
                        str = str + `<li><a onclick="
                            selected_id = ${r.id}
                            topicClickHandler(${r.id});    
                        " href="/create/${r.title}">${r.title}</a></li>`;
                    }
                    document.querySelector('ul').innerHTML = str;
                });
            }

            function topic(){
                fetch('/topics/'+selected_id)
                .then(function(type){
                    return type.json();
                })
                .then(function(result){
                    document.querySelector('article').innerHTML = `<h1>${result.title}</h1>${result.body}`;
                })
            }

            function welcome(){
                document.querySelector('article').innerHTML = `<h1>Welcome</h1>Hello, Front end`;
            }

            function delHandler(){
                fetch('/topics/'+selected_id, {method:'DELETE'})
                    .then(function(type){return type.json();})
                    .then(function(result){
                        nav();
                        welcome();
                    })
            }

            function createSubmitHandler(){
                event.preventDefault();
                var form = event.target;
                fetch('/topics', {
                        method:'POST',
                        body:JSON.stringify({
                            title:form.title.value,
                            body:form.body.value 
                        }),
                        headers:{
                            'Content-Type':'application/json'
                        }
                    })
                    .then(function(type){return type.json();})
                    .then(function(result){
                        nav();
                        selected_id = result.id;
                        topic(selected_id);
                    })
            }

            function create(){
                history.pushState({}, 'create', '/create');
                document.querySelector('article').innerHTML = `
                    <form action="/topics" method="POST" onsubmit="createSubmitHandler();">
                        <p><input type="text" name="title" placeholder="title"></p>
                        <p><input type="text" name="body" placeholder="body"></p>
                        <p><input type="submit"></p>
                    </form>
                `
            }

            function updateSubmitHandler(){
                event.preventDefault();
                var form = event.target;
                fetch('/topics/'+selected_id, {
                        method:'PUT',
                        body:JSON.stringify({
                            title:form.title.value,
                            body:form.body.value 
                        }),
                        headers:{
                            'Content-Type':'application/json'
                        }
                    })
                    .then(function(type){return type.json();})
                    .then(function(result){
                        nav();
                        selected_id = result.id;
                        topic(selected_id);
                    })
            }

            function update(){
                history.pushState({}, 'update', '/update');
                fetch('/topics/'+selected_id)
                .then(function(type){
                    return type.json();
                })
                .then(function(result){
                    document.querySelector('article').innerHTML = `
                    <form action="/topics/${selected_id}" method="PUT" onsubmit="updateSubmitHandler();">
                        <p><input type="text" value="${result.title}" name="title" placeholder="title"></p>
                        <p><input type="text" value="${result.body}" name="body" placeholder="body"></p>
                        <p><input type="submit"></p>
                    </form>
                `
                });
            }
            nav();
            control();
            var pathname = location.pathname;
            if(pathname === '/'){                
                welcome();
            } else if(pathname === '/create'){
                create();
            } else if(pathname === '/update'){
                update();
            } else {
                var match = location.pathname.match(/\/([0-9]+)/);
                var selected_id = match[1];
                topic();
            }
        </script>
    </body>
</html>

DATA SOURCE

동기적인(synchronous) 통신 사례

비동기적인(asynchronous) 통신 사례

Fetch API 이용

async, await 이용

https://jsbin.com/berojuy/edit?html,output

Clone this wiki locally