본문 바로가기

만들고 싶은거 만들기

광고 수익을 창출할 웹사이트 만들어보기 2-6(React-Flask연동 feat.CORS)

연말이라 시간이 없으니 바로 들어간다.


일단 첫번째로 할 일은 이미지 생성할 Text 입력창하고 버튼 UI 만드는 것이다.

(나 프론트앤드는 하나도 몰라서 찎찎피티보고 따라할거임.)

 

App.js를 수정해준다.

import React, { useState } from 'react';

function App() {
    const [prompt, setPrompt] = useState('');

    const handleGenerate = () => {
        alert(`Prompt: ${prompt}`);
    };

    return (
        <div style={{ textAlign: 'center', padding: '20px' }}>
            <h1>Emoji Generator</h1>
            <input
                type="text"
                placeholder="Enter your prompt"
                value={prompt}
                onChange={(e) => setPrompt(e.target.value)}
                style={{ padding: '10px', width: '300px', marginRight: '10px' }}
            />
            <button onClick={handleGenerate} style={{ padding: '10px 20px' }}>
                Generate
            </button>
        </div>
    );
}

export default App;

 

설명은 대략 아래와 같다.

 

  • UI 구성 설명
    • 텍스트 입력 필드: 사용자가 이모티콘을 생성할 프롬프트를 입력합니다.
    • 버튼: 버튼을 클릭하면 현재 입력된 프롬프트를 alert로 출력합니다.
  • 결과 확인
    • 브라우저에서 새로고침 없이 바로 확인 가능합니다.
    • 입력창에 텍스트를 입력하고 "Generate" 버튼을 눌러 alert로 출력되는지 확인하세요.

소스 변경하고 바로 테스트 렛츠고.

깔끔하고 좋다잉.

이제 백엔드와 연동하는 작업 들어가겠다.


일단 필요한 라이브러리부터 받아준다.

터미널에 입력한다.

npm install axios

 

axios는 자바스크립트에서 HTTP 요청을 쉽게 처리할 수 있게 해주는 라이브러리다.

간단히 말하면, 클라이언트(React.js 같은 프론트엔드 애플리케이션)에서 서버(백엔드)로 데이터를 주고받는 데 사용한다.

 

좋다. 설치가 되었으면 App.js 를 수정해준다.

import React, { useState } from 'react';
import axios from 'axios';

function App() {
    const [prompt, setPrompt] = useState('');
    const [imageUrl, setImageUrl] = useState(null); // 이미지 URL 상태 추가
    const [loading, setLoading] = useState(false);  // 로딩 상태 추가

    const handleGenerate = async () => {
        if (!prompt.trim()) {
            alert("Please enter a prompt.");
            return;
        }

        setLoading(true);
        setImageUrl(null);

        try {
            const response = await axios.post('http://127.0.0.1:5000/generate', { prompt });
            setImageUrl(response.data.image_url);
        } catch (error) {
            console.error("Error generating image:", error);
            alert("Failed to generate image. Please try again.");
        } finally {
            setLoading(false);
        }
    };

    return (
        <div style={{ textAlign: 'center', padding: '20px' }}>
            <h1>Emoji Generator</h1>
            <input
                type="text"
                placeholder="Enter your prompt"
                value={prompt}
                onChange={(e) => setPrompt(e.target.value)}
                style={{ padding: '10px', width: '300px', marginRight: '10px' }}
            />
            <button onClick={handleGenerate} style={{ padding: '10px 20px' }}>
                {loading ? "Generating..." : "Generate"}
            </button>

            {imageUrl && (
                <div style={{ marginTop: '20px' }}>
                    <h3>Generated Image:</h3>
                    <img src={imageUrl} alt="Generated" style={{ width: '300px', height: '300px' }} />
                </div>
            )}
        </div>
    );
}

export default App;

 

 

소스의 동작순서는 아래와 같다.

동작 순서

  1. 사용자가 텍스트를 입력하고 "Generate" 버튼을 클릭.
  2. 입력한 텍스트(prompt)가 백엔드로 전송됨 /generate.
  3. 백엔드(flask server)에서 이미지 URL을 생성하여 프론트엔드(React server)에 전달.
  4. 프론트엔드 (React server) 는 받은 URL을 이용해 이미지를 화면에 표시.

어렵진 않다. 바로 테스트 해본다.

테스트 할때 주의할 점은 두개의 서버 다 기동이 되어있어야 테스트가 가능하다. (ㅋㅋ 당연한말하네 얘)

 

 

 

어림도 없지 바로실패 ㅋㅋ

이유를 찾아보는데 프론트앤드 백앤드 통신과정에서 어디가 문제인지 찾기가 어려웠따.

일단 첫번째로 어디가 문제인지 찾는게 우선이여서 Postman으로 백앤드서버에 요청을 보내보기로 한다.

 

아주 잘나와~ 

그렇다면 범인은 프론트앤드....? 하면서 어디가 문제인지 로직을 훑어보는데도 안나온다.

 

그러던 중 CORS라는 Cross-Origin Resource Sharing 문제를 찾았다.

 

CORS(Cross-Origin Resource Sharing)란

다른 도메인 간의 요청을 허용하거나 제한하기 위해 사용되는 브라우저 보안 정책

기본적으로 브라우저는 동일 출처(origin) 정책에 따라 다른 도메인 요청을 차단하지만,

서버에서 CORS 헤더를 설정하면 이를 허용할 수 있다.

이를 통해 클라이언트(프론트엔드)와 서버 간 안전하게 데이터를 주고받을 수 있게 해준다.

포트 번호가 다르거나 프로토콜, 서브도메인이 다르면 다른 출처(Origin)로 간주된다는 거다.

  • 동일한 출처:
    • http://localhost:3000 (React)
    • http://localhost:3000/api (Flask 백엔드)
  • 다른 출처 (CORS 문제 발생):
    • http://localhost:3000 (React)
    • http://localhost:5000 (Flask 백엔드)
    • 포트가 다르기 때문에 브라우저는 서로 다른 출처로 인식.

그래서 두 서버가 통신하려면 CORS 옵션을 허용해줘야 한다고 한다.

 

서버(Flask)에서 CORS를 허용하면 해결 가능하다고 하니 진행해본다.

별거없다.

플라스크서버에서 cors관련 라이브러리를 설치해준 뒤 아래코드를 추가해주자.

pip install flask-cors
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/generate": {"origins": "http://localhost:3000"}})

 

나중에 실제 배포할땐 localhost가 아니라 도메인으로 바꿀 예정이지만 지금은 로컬에서 테스트중이니 일단 지정해주자.

 

CORS 옵션까지 넣고 다시 테스트해보겠다.

짜자잔 ~~~~~ 너무 잘나온다잉~ 매우 만족스럽다.


좋다. 이걸로 연계를 완료했으니 이제 남은 파트는 

 

  • UI 스타일 업그레이드
  • 이미지 카톡이나 디스코드에 공유하기 기능 추가
  • 배포

정도가 되겠다. 뭘할지는 자유다. 한번 해보자구~

 

다음화에 계속..............