Flask를 사용하여 fullstack twitter 클론 구축 및 반응 | 1부

안녕하십니까, 지역사회!이것은 제가 여기 있는 첫 번째 댓글입니다. 이 댓글에서 React와 Flask를 사용하여 간단한fullstack 트위터 복제를 만드는 방법을 보여드리고 싶습니다.이것은 세 부분으로 구성된 시리즈가 될 것이며, 이 부분에서 우리는 응용 프로그램을 구축할 것이다.
시작하기 전에, 나는 당신이 flask,react,javascript,python과 html를 알고 있다고 가정합니다

프로젝트 설정


나는 VSCode를 나의 IDE로 사용할 것이다. 그러나 너는 네가 좋아하는 모든 것을 사용할 수 있다. (Pycharm, Webstorm, Atom이 바로 몇 가지 예이다.)IDE에 대한 설명을 표시합니다.

프로젝트 만들기


항목을 저장할 폴더를 만들고 터미널 창을 엽니다.UNIX 터미널(BASH SHELL)을 사용하여 작업하는 것을 좋아하지만 GUI 기반 파일 브라우저를 사용할 수도 있습니다.backend 폴더를 만듭니다.
mkdir backend
create-react-app 폴더를 만들고react 프로그램을 초기화합니다.
npx create-react-app frontend
지금, 너는 두 개의 폴더, 앞부분과 뒷부분이 있어야 한다.
$ ls
backend
frontend
아름답다이제 백엔드를 설정합시다.frontend 및 flask를 위한 가상 환경을 만듭니다.
사용 가능cd 또는 가상 환경을 전혀 사용하지 않음!
python3 -m venv venv && . venv/bin/activate
이것은 pipenv라는 가상 환경을 만들고 활성화해야 한다.이제 venv 기본 프로젝트 폴더에 들어가서 VSCode를 사용하여 열기 cd 를 입력합니다.

기본 코드를 만듭니다.프로젝트


이제 백엔드를 설정합시다.우선, 우리는 플라스크를 설치해야 한다.
pip install flask
virtualenv가 활성화되었는지 확인합니다.
이제 Flask 라는 파일을 만듭니다.이것은 우리 백엔드의 메인 파일이 될 것이다.
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, world!"

if __name__ == "__main__":
    app.run(debug=True) # debug=True restarts the server everytime we make a change in our code
이제 입력을 통해
python3 app.py
서버가 작동하는지 테스트해 봅시다.필요한 경우 브라우저에서 localhost:5000 또는 app.py 와 같은 Insomnia 에 액세스할 수 있습니다.테스트post 방법에 대해 REST Client 을 사용합니다. 이것은 명령행 유틸리티이지만 GUI REST 클라이언트를 사용할 수 있습니다.
데이터베이스에 대해서는 cURL, 즉 Flask-SQLAlchemy 또는 SQLAlchemy 표시sqlite3를 사용할 수 있습니다.먼저 Flask 종료 서버를 눌러서 서버를 닫고 설치CTRL + C합시다.
pip install flask-sqlalchemy
이제 flask-sqlalchemy로 돌아가서 가져오겠습니다 app.py.
from flask_sqlalchemy import SQLAlchemy
우리가 정의한 곳flask-sqlalchemy에 다음 코드를 쓰십시오.
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///twitter.db"

# DB
db = SQLAlchemy(app)
class Users(db.Model):
    id = db.Column('student_id', db.Integer, primary_key = True) # primary_key makes it so that this value is unique and can be used to identify this record.
    username = db.Column(db.String(24))
    email = db.Column(db.String(64))
    pwd = db.Column(db.String(64))

    # Constructor
    def __init__(self, username, email, pwd):
        self.username = username
        self.email = email
        self.pwd = pwd
이 코드의 역할은 우선 데이터베이스 파일을 app 로 설정하는 것이다.만약 네가 원한다면, 너는 이 이름을 바꿀 수 있다.그리고 보시다시피 twitter.db 클래스는 users 표의 열을 보여 줍니다.매우 표준적인 SQL입니다.
현재 Model 함수의 users 문장 위에 잠시 쓰십시오.
db.create_all()
파일은 다음과 같습니다.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///twitter.db"

# DB
db = SQLAlchemy(app)
class Users(db.Model):
    id = db.Column('student_id', db.Integer, primary_key = True) # primary_key makes it so that this value is unique and can be used to identify this record.
    username = db.Column(db.String(24))
    email = db.Column(db.String(64))
    pwd = db.Column(db.String(64))

    # Constructor
    def __init__(self, username, email, pwd):
        self.username = username
        self.email = email
        self.pwd = pwd

@app.route('/')
def index():
    return "Hello, world!"

if __name__ == "__main__":
    app.run(debug=True)
서버를 시작하고 방문localhost:5000하거나 원하는 return 클라이언트를 사용하여 요청index을 수행합니다.예를 들어, GET 에서 입력할 수 있습니다.
curl "http://localhost:5000"
같은 대답을 받을 수 있을 것 같지만, 폴더에서 찾으면 REST 이라는 새 파일을 발견할 수 있습니다.이것은 너의 데이터베이스다.cURL, twitter.db 또는 MYSQL와 달리 MariaDB 서버가 필요 없이 작업할 수 있습니다.

기본 때 축적 경로


이제 응용 프로그램에 더 많은 루트를 추가하여 기본 MongoDB (읽기 업데이트 삭제 만들기) 작업을 수행합니다.우선, 색인 루트를 완전히 삭제합니다.우리는 그것을 필요로 하지 않는다.나는 나의 모든 노선 앞에 sqlite 을 더할 것이다.
@app.route("/api/users", methods=["GET", "POST", "DELETE"])
def users():
    method = request.method
    if (method.lower() == "get"): # READ
        users = Users.query.all()
        return jsonify([{"id": i.id, "username": i.username, "email": i.email, "password": i.pwd} for i in users]) # Get all values from db
    elif (method.lower() == "post"): # CREATE
        try:
            username = request.json["username"]
            email = request.json["email"]
            pwd = request.json["pwd"]
            if (username and pwd and email): # Checks if username, pwd or email are empty
                try:
                    user = Users(username, email, pwd) # Creates a new record
                    db.session.add(user) # Adds the record for committing
                    db.session.commit() # Saves our changes
                    return jsonify({"success": True})
                except Exception as e:
                    return ({"error": e})
            else:
                return jsonify({"error": "Invalid form"}) # jsonify converts python vars to json
        except:
            return jsonify({"error": "Invalid form"})
    elif (method.lower() == "delete"): # DESTROY
        try:
            uid = request.json["id"]
            if (uid):
                try:
                    user = Users.query.get(uid) # Gets user with id = uid (because id is primary key)
                    db.session.delete(user) # Delete the user
                    db.session.commit() # Save
                    return jsonify({"success": True})
                except Exception as e:
                    return jsonify({"error": e})
            else:
                return jsonify({"error": "Invalid form"})
        except:
            return jsonify({"error": "m"})
  • 잠시 후 PUT 방법을 검토하겠습니다*
    현재 우리의 응용 프로그램에는 CRUD 라는 노선이 있다.다양한 HTTP 방법을 통해 생성, 읽기 및 제거 작업을 수행할 수 있습니다.추가 정보here
  • 이제 우리의 코드는 다음과 같아야 한다.
    from flask import Flask, request, jsonify
    from flask_sqlalchemy import SQLAlchemy
    
    from flask import Flask, request, jsonify
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///twitter.db"
    
    # DB
    db = SQLAlchemy(app)
    class Users(db.Model):
        id = db.Column('student_id', db.Integer, primary_key = True) # primary_key makes it so that this value is unique and can be used to identify this record.
        username = db.Column(db.String(24))
        email = db.Column(db.String(64))
        pwd = db.Column(db.String(64))
    
        # Constructor
        def __init__(self, username, email, pwd):
            self.username = username
            self.email = email
            self.pwd = pwd
    
    # Routes
    
    # Users
    @app.route("/api/users", methods=["GET", "POST", "DELETE"])
    def users():
        method = request.method
        if (method.lower() == "get"): # READ
            users = Users.query.all()
            return jsonify([{"id": i.id, "username": i.username, "email": i.email, "password": i.pwd} for i in users]) # Get all values from db
        elif (method.lower() == "post"): # CREATE
            try:
                username = request.json["username"]
                email = request.json["email"]
                pwd = request.json["pwd"]
                if (username and pwd and email): # Checks if username, pwd or email are empty
                    try:
                        user = Users(username, email, pwd) # Creates a new record
                        db.session.add(user) # Adds the record for committing
                        db.session.commit() # Saves our changes
                        return jsonify({"success": True})
                    except Exception as e:
                        return ({"error": e})
                else:
                    return jsonify({"error": "Invalid form"}) # jsonify converts python vars to json
            except:
                return jsonify({"error": "Invalid form"})
        elif (method.lower() == "delete"): # DESTROY
            try:
                uid = request.json["id"]
                if (uid):
                    try:
                        user = Users.query.get(uid) # Gets user with id = uid (because id is primary key)
                        db.session.delete(user) # Delete the user
                        db.session.commit() # Save
                        return jsonify({"success": True})
                    except Exception as e:
                        return jsonify({"error": e})
                else:
                    return jsonify({"error": "Invalid form"})
            except:
                return jsonify({"error": "m"})
                    return ({"error": "Invalid form"})
            except:
                return ({"error": "Invalid form"})
    
    if __name__ == "__main__":
        app.run(debug=True)
    
    우리 이 사람을 운전해 봅시다!
    우선 /api 집행 /api/users 에 대한 요청을 하겠습니다.
    curl "http://localhost:5000/api/users"
    # OUTPUT: []
    
    우리는 데이터베이스에 데이터가 없기 때문에 빈 그룹을 얻었다
    이제 데이터를 좀 드리겠습니다.일부 데이터를 사용하여 GET/api/users 요청을 실행합니다.
    curl -X POST -H "Content-Type: application/json" -d '{"username": "foo", "email": "[email protected]", "pwd": "bar"}' "http://localhost:5000/api/users"
    
    POST 데이터를 다시 입력하면 이미 기록되어 있음을 알 수 있습니다.이제 사용자를 삭제하겠습니다.
    curl -X DELETE -H "Content-Type: application/json" -d '{"id": 1}' "http://localhost:5000/api/users"
    
    만약 우리가 데이터를 조회한다면, 우리는 빈 문자열을 되돌려야 한다.우리는 잠시 후에 다시 한다/api/users.
    이것은 마땅히 우리가 병을 굽는 데 응용한 것이다.서버 계속 및 중지 (GET

    프런트엔드 만들기


    이제 앞부분에 주목하자.터미널의 PUT 폴더 (또는 원하는 폴더) 를 열고 다음을 입력합니다.
    npm start
    
    이것은 localhost:3000에 웹 페이지를 열 것입니다.

    홈 페이지 만들기


    기본 템플릿 ^C 은 우리가 필요로 하는 것이 아니므로 frontendcreate-react-app 폴더의 내용을 삭제합니다.응용 프로그램이 무너지는 것을 볼 수 있지만, 괜찮아요.또한 생성public,src,public/index.html,src/index.js,src/components,src/components/App.jsx,src/components/Home.jsx,src/components/Navbar.jsx
    rm -r public/* src/*  
    mkdir src/components  
    touch public/index.html src/index.js src/components/App.jsx src/components/Home.jsx src/components/Navbar.jsx
    
    이제 색인 코드를 설정합시다.html
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Quickr</title>
            <!-- W3CSS -->
            <link rel="stylesheet" href="https://w3schools.com/w3css/4/w3.css" />
        </head>
        <body>
            <div id="root"></div>
        </body>
    </html>
    
    css 스타일로 W3CSS 사용하고 있습니다. 왜냐하면 빠르고 사용하기 쉽기 때문입니다.
    현재 모든 javascript 파일에 대해:
    // src/index.js
    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./components/App";
    
    ReactDOM.render(<App />, document.getElementById("root"));
    
    // src/components/App.jsx
    import React from "react";
    import Home from "./Home";
    import Navbar from "./Navbar";
    
    function App() {
        return (
            <React.Fragment>
                <Navbar />
                <Home />
            </React.Fragment>
        );
    }
    
    export default App;
    
    
    // src/components/Home.jsx
    import React from "react";
    
    function Home() {
        return (
            <React.Fragment>
                <div
                    className="w3-container w3-center w3-blue"
                    style={{ padding: "2rem" }}>
                    <h1 className="w3-jumbo">Quickr - Quick Twitter</h1>
                    <button
                        className="w3-button w3-pink"
                        style={{ marginRight: "1rem" }}>
                        Login
                    </button>
                    <button className="w3-button w3-pink">Register</button>
                </div>
    
                <div
                    className="w3-container w3-blue"
                    style={{ padding: "2rem", marginTop: "2rem" }}>
                    <h2>Lorem ipsum dolor sit amet</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                        Integer consectetur libero nibh, non sodales urna malesuada
                        nec. Sed tortor eros, blandit eget fringilla at, gravida a
                        nibh. Etiam dui nulla, aliquam vitae purus a, auctor
                        malesuada arcu. Vestibulum venenatis orci nisl, sed
                        elementum leo tincidunt eget. Nullam convallis nisi in.
                    </p>
                </div>
    
                <div
                    className="w3-container w3-blue"
                    style={{ padding: "2rem", marginTop: "2rem" }}>
                    <h2>Lorem ipsum dolor sit amet</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                        Integer consectetur libero nibh, non sodales urna malesuada
                        nec. Sed tortor eros, blandit eget fringilla at, gravida a
                        nibh. Etiam dui nulla, aliquam vitae purus a, auctor
                        malesuada arcu. Vestibulum venenatis orci nisl, sed
                        elementum leo tincidunt eget. Nullam convallis nisi in.
                    </p>
                </div>
    
                <div
                    className="w3-container w3-blue"
                    style={{ padding: "2rem", marginTop: "2rem" }}>
                    <h2>Lorem ipsum dolor sit amet</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                        Integer consectetur libero nibh, non sodales urna malesuada
                        nec. Sed tortor eros, blandit eget fringilla at, gravida a
                        nibh. Etiam dui nulla, aliquam vitae purus a, auctor
                        malesuada arcu. Vestibulum venenatis orci nisl, sed
                        elementum leo tincidunt eget. Nullam convallis nisi in.
                    </p>
                </div>
            </React.Fragment>
        );
    }
    
    export default Home;
    
    // src/components/Navbar.jsx
    import React from "react";
    
    function Navbar() {
        return (
            <div className="w3-bar w3-black">
                <a className="w3-bar-item w3-button" href="/">
                    Quickr
                </a>
                <div style={{ float: "right" }}>
                    <a className="w3-bar-item w3-button" href="/">
                        Login
                    </a>
                    <a className="w3-bar-item w3-button" href="/">
                        Register
                    </a>
                </div>
            </div>
        );
    }
    
    export default Navbar;
    
    마지막으로 당신의 사이트는 다음과 같습니다.

    이제 기능을 추가합시다!

    프런트엔드에 백엔드 연결


    이제 로그인과 등록을 실현하겠습니다.우리 이전 노선 기억나?함수로 바꿔보도록 하겠습니다.
    def getUsers():
        users = Users.query.all()
        return [{"id": i.id, "username": i.username, "email": i.email, "password": i.pwd} for i in users]
    
    def addUser(username, email, pwd):
        if (username and pwd and email):
            try:
                user = Users(username, email, pwd)
                db.session.add(user)
                db.session.commit()
                return True
            except Exception as e:
                print(e)
                return False
        else:
            return False
    
    def removeUser(uid):
        uid = request.json["id"]
        if (uid):
            try:
                user = Users.query.get(uid)
                db.session.delete(user)
                db.session.commit()
                return True
            except Exception as e:
                print(e)
                return False
        else:
            return False
    
    이제 로그인하고 등록하는api 루트를 추가합니다.나는 예전처럼 /api 을 내 노선의 접두사로 사용할 것이다.
    @app.route("/api/login", methods=["POST"])
    def login():
        try:
            email = request.json["email"]
            password = request.json["pwd"]
            if (email and password):
                users = getUsers()
                # Check if user exists
                return jsonify(len(list(filter(lambda x: x["email"] == email and x["password"] == password, users))) == 1)
            else:
                return jsonify({"error": "Invalid form"})
        except:
            return jsonify({"error": "Invalid form"})
    
    @app.route("/api/register", methods=["POST"])
    def register():
        try:
            email = request.json["email"]
            email = email.lower()
            password = request.json["pwd"]
            username = request.json["username"]
            # Check to see if user already exists
            users = getUsers()
            if(len(list(filter(lambda x: x["email"] == email, users))) == 1):
                return jsonify({"error": "Invalid form"})
            # Email validation check
            if not re.match(r"[\w\._]{5,}@\w{3,}.\w{2,4}", email):
                return jsonify({"error": "Invalid form"})
            addUser(username, email, password)
            return jsonify({"success": True})
        except:
            return jsonify({"error": "Invalid form"})
    
    우리의 등록 방법에서 우리는 몇 가지 형식 검증을 진행하였다.전자 메일이 등록되었는지, 전자 메일이 유효한지 확인합니다.이제 테스트를 해 봅시다.서버를 시작하고 요청을 합니다.
    # REGISTER
    curl -X POST -H "Content-Type: application/json" -d '{"email": "[email protected]", "pwd": "foobar", "username": "foobar"}' "http://localhost:5000/api/register" 
    
    # LOGIN
    curl -X POST -H "Content-Type: application/json" -d '{"email": "[email protected]", "pwd": "azeez"}' "http://localhost:5000/api/login"
    
    이제 CLI를 사용하여 데이터베이스에 로그인할 수 있습니다.단, 우리는 사용자가 이 사이트를 사용하여 로그인할 수 있도록 허락해야 한다.우리 앞으로 나가자.
    그래서 나는 두 개의 서류Login.jsxRegister.jsx를 만들었다.이 파일들은 각각 로그인과 등록 폼을 포함한다.사용자는 자신의 태그를 사용할 수 있지만 내 태그를 사용하고 싶은 사용자는 다음과 같이 할 수 있습니다.
    // src/components/Login.jsx
    import React, { Component } from "react";
    
    class Login extends Component {
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        LOGIN
                    </div>
                    <div className="w3-container">
                        <form>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    class="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    class="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Login
                                </button>
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Login;
    
    // src/components/Register.jsx
    import React, { Component } from "react";
    
    class Register extends Component {
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        REGISTER
                    </div>
                    <div className="w3-container">
                        <form>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    class="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="username">Username</label>
                                <input
                                    type="username"
                                    class="w3-input w3-border"
                                    id="text"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    class="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Register
                                </button>
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Register;
    
    좋아, 우리는 이미 표시를 완성했지만, 우리는 어떻게 다른 방식으로 그것을 나타낼 수 있을까?예를 들어 https://mywebsite.com/login 를 입력하면 로그인 페이지를 봐야 합니다.이것은 사용react-router-dom을 통해 완성할 수 있다.먼저 설치react-router-dom
    npm i react-router-dom
    
    지금 우리는 App.jsx 에서 그것을 실현할 것이다
    // src/components/App.jsx
    import React from "react";
    import Home from "./Home";
    import Navbar from "./Navbar";
    import Login from "./Login";
    import Register from "./Register";
    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    
    function App() {
        return (
            <React.Fragment>
                <Navbar />
                <Router>
                    <Route path="/" exact component={Home} />
                    <Route path="/login" exact component={Login} />
                    <Route path="/register" exact component={Register} />
                </Router>
            </React.Fragment>
        );
    }
    
    export default App;
    
    나는 또 Navbar.jsx 중의 노선을 갱신했다.
    // src/components/Navbar.jsx
    import React from "react";
    
    function Navbar() {
        return (
            <div className="w3-bar w3-black">
                <a className="w3-bar-item w3-button" href="/">
                    Quickr
                </a>
                <div style={{ float: "right" }}>
                    <a className="w3-bar-item w3-button" href="/login"> // Updated
                        Login
                    </a>
                    <a className="w3-bar-item w3-button" href="/register"> // Updated
                        Register
                    </a>
                </div>
            </div>
        );
    }
    
    export default Navbar;
    
    현재 네비게이션 표시줄의 로그인과 등록 단추를 누르면 우리가 만든 구성 요소를 볼 수 있습니다.이제 구성 요소에 기능을 추가합시다.

    로그인


    우선, axios라는 프로그램을 설치합시다.
    npm i axios
    
    이제 함수를 추가하여 POST 요청을 백엔드로 보냅니다.
    // Login.jsx
    import React, { Component } from "react";
    import axios from "axios";
    
    class Login extends Component {
        login = (e) => {
            e.preventDefault();
            axios
                .post("http://localhost:5000/api/login", {
                    email: document.getElementById("email").value,
                    pwd: document.getElementById("password").value,
                })
                .then((res) => {
                    console.log(res.data);
                });
        };
    
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        LOGIN
                    </div>
                    <div className="w3-container">
                        <form onSubmit={this.login}>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    className="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    className="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Login
                                </button>
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Login;
    
    import React, { Component } from "react";
    import axios from "axios";
    
    class Register extends Component {
        register = (e) => {
            e.preventDefault();
            axios
                .post("http://localhost:5000/api/register", {
                    email: document.getElementById("email").value,
                    username: document.getElementById("username").value,
                    pwd: document.getElementById("password").value,
                })
                .then((res) => {
                    console.log(res.data);
                });
        };
    
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        REGISTER
                    </div>
                    <div className="w3-container">
                        <form onSubmit={this.register}>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    className="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="username">Username</label>
                                <input
                                    type="text"
                                    className="w3-input w3-border"
                                    id="username"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    className="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Register
                                </button>
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Register;
    
    따라서 우리가 여기서 하는 일은 언제든지 폼을 제출하면 백엔드에 로그인과 등록 루트를 요청할 것입니다.우리가 회답을 받았을 때, 우리는 기록할 것이다.이제 등록표에 스팸 데이터를 입력하고 윈도우즈/Linux에서 Ctrl+Shift+I 또는 Mac에서 Cmd+Option+I 를 눌러 브라우저 컨트롤러(또는 devtools)를 엽니다.등록 버튼을 누르면 콘솔에서 다음과 같은 오류가 표시됩니다.

    현재 이 오류는 이른바 CORS가 실시한 안전 조치이다.이 문제를 돌리기 위해서 우리는 백엔드에 flask-cors라는 물건을 설치해야 한다.
    pip install flask-cors
    
    이제 app.py 의 시작을 다음으로 변경합니다.
    from flask import Flask, request, jsonify
    from flask_sqlalchemy import SQLAlchemy
    from flask_cors import CORS
    import re
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///twitter.db"
    CORS(app)
    # ...
    
    지금register를 누르면 컨트롤러에서 볼 수 있습니다 {success: true}.지금 같은 전자 메일과 비밀번호로 로그인하면 컨트롤러에서 볼 수 있습니다 true. 이것은 모든 것이 정상이라는 것을 의미합니다!이제 사용자에게 피드백을 드리겠습니다.Alert.jsx라는 새 파일을 생성하여 다음과 같이 넣습니다.
    import React from "react";
    
    function Alert(props) {
        return (
            <div
                className="w3-pale-red w3-text-red w3-border w3-border-red w3-round-large"
                style={{ padding: "1rem", marginTop: "1rem" }}>
                {props.message}
            </div>
        );
    }
    
    export default Alert;
    
    Alert는 현재 다시 사용할 수 있는 구성 요소입니다. 코드의 어느 곳에서든 사용할 수 있습니다. 메시지를 줄 수 있습니다.이 메시지는 빨간색 배경과 빨간색 텍스트로 표시됩니다.이 구성 요소는 Register.jsx 에서 사용할 수 있습니다.
    import React, { Component } from "react";
    import axios from "axios";
    import Alert from "./Alert";
    
    class Register extends Component {
        state = { err: "" };
    
        register = (e) => {
            e.preventDefault();
            axios
                .post("http://localhost:5000/api/register", {
                    email: document.getElementById("email").value,
                    username: document.getElementById("username").value,
                    pwd: document.getElementById("password").value,
                })
                .then((res) => {
                    if (res.data.error) {
                        this.setState({ err: res.data.error });
                    } else {
                        this.setState({ register: true });
                    }
                });
        };
    
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        REGISTER
                    </div>
                    <div className="w3-container">
                        {this.state.err.length > 0 && (
                            <Alert
                                message={`Check your form and try again! (${this.state.err})`}
                            />
                        )}
                        <form onSubmit={this.register}>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    class="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="username">Username</label>
                                <input
                                    type="text"
                                    class="w3-input w3-border"
                                    id="username"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    class="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Register
                                </button>
                                {this.state.register && <p>You're registered!</p>}
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Register;
    
    이제 잘못된 전자 메일을 입력한 경우 (내 정규 표현식에 따라 유효한 전자 메일은.와_, @, 3 개 이상의 알파벳 문자, 하나.와 2-4 개 이상의 알파벳 문자를 포함하는 5 개 이상의 알파벳 문자를 포함하는 전자 메일입니다.

    경탄했어Login.jsx 오류 처리도 사용할 수 있습니다.
    import React, { Component } from "react";
    import axios from "axios";
    import Alert from "./Alert";
    
    class Login extends Component {
        state = { err: "" };
    
        login = (e) => {
            e.preventDefault();
            axios
                .post("http://localhost:5000/api/login", {
                    email: document.getElementById("email").value,
                    pwd: document.getElementById("password").value,
                })
                .then((res) => {
                    if (res.data.error) {
                        this.setState({ err: res.data.error });
                    } else {
                        this.setState({ login: true });
                    }
                });
        };
    
        render() {
            return (
                <div className="w3-card-4" style={{ margin: "2rem" }}>
                    <div className="w3-container w3-blue w3-center w3-xlarge">
                        LOGIN
                    </div>
                    <div className="w3-container">
                        {this.state.err.length > 0 && (
                            <Alert
                                message={`Check your form and try again! (${this.state.err})`}
                            />
                        )}
                        <form onSubmit={this.login}>
                            <p>
                                <label htmlFor="email">Email</label>
                                <input
                                    type="email"
                                    class="w3-input w3-border"
                                    id="email"
                                />
                            </p>
                            <p>
                                <label htmlFor="password">Password</label>
                                <input
                                    type="password"
                                    class="w3-input w3-border"
                                    id="password"
                                />
                            </p>
                            <p>
                                <button type="submit" class="w3-button w3-blue">
                                    Login
                                </button>
                                {this.state.register && <p>You're logged in!</p>}
                            </p>
                        </form>
                    </div>
                </div>
            );
        }
    }
    
    export default Login;
    
    이제 잘못된 자격 증명을 입력하면 다음과 같은 결과를 얻을 수 있습니다.

    결론


    아름답다이제 RESTful API를 사용하여 플라스크를 연결하고 함께 반응하는 방법을 배웠습니다.다음 부분에서, 우리는 추문을 발표하고 보는 기능을 추가할 것이다.이 게시물은 이미 매우 길다.나는 유튜브에 그것에 관한 동영상을 만들어 보려고 한다. 만약 내가 이렇게 한다면, 나는 반드시 그것을 여기에 연결할 것이다.모든 코드는 위에서 찾을 수 있다.이게 첫 번째 댓글에 너무 길어요!

    좋은 웹페이지 즐겨찾기