내가 하려는 작업은 크게 다음과 같다.
1. 백준 사이트의 유저 정보와 문제 정보를 가져온다. (url을 통해)
2. 이 정보들을 바탕으로 추천 시스템을 돌려서 추천 문제를 뽑는다.
3. 뽑은 추천 문제를 DOM으로 백준 사이트에 삽입한다.
1.은 자바스크립트가, 2는 플라스크가, 3은 다시 자바스크립트가 수행해야한다.
즉 둘이서 통신을 해야만 내가 하려는 작업을 할 수 있다.
자바스크립트에 window.location.href라는 편리한 기능이 있다.
이를 통해서 현재 사이트의 url을 쉽게 가져올 수 있다.
가져온 url을 fetch 함수를 통해서 플라스크에게 건내줄 수 있다.
다른 함수들도 있는데, fetch가 가장 사용하기 간단하다. 좀 더 복잡한 처리가 필요할 때는 ajax가 더 용이하다고 한다.
const response = fetch('http://127.0.0.1:8080/send_url', { method: 'POST', body: JSON.stringify({ url: window.location.href }), headers: { 'Content-Type': 'application/json' }
fetch 함수:
fetch 함수는 웹 리소스(일반적으로 URL)를 가져오기 위한 JavaScript API다. fetch 함수를 사용하여 플라스크 서버로 HTTP POST 요청을 보낸다.
body: JSON.stringify({ url: window.location.href }) :
이 부분은 요청의 본문(body) 데이터를 설정한다. JSON.stringify 함수를 사용하여 JavaScript 객체를 JSON 문자열로 변환하고, 이 JSON 문자열은 요청의 본문으로 보내진다. 현재 페이지의 URL을 "url" 키 아래에 넣었다.
headers: { 'Content-Type': 'application/json' }:
이 옵션은 요청 헤더를 설정한다. 'application/json'은 서버에게 요청 본문이 JSON 형식임을 알린다.
위의 자바스크립트에서 url을 post로 건냈으니 플라스크가 이를 받아야한다.
@app.route('/send_url', methods=['POST'])
다음과 같이 '/send_url'에 대한 HTTP POST 요청을 처리하는 Flask 애플리케이션의 엔드포인트를 정의할 수 있다. 위의 자바스크립트 코드에서 '127.0.0.1:8080/send_url'로 정보를 건냈다.
플라스크는 이 엔드포인트를 감시하고 있다가 어떤 요청이 이 엔드포인트에 도달하면 해당 함수를 호출할 것이다. 또 자바스크립트가 url을 건냈으므로, 즉 post했으므로 method는 post가 된다. (클라이언트가 post하면 해당 함수가 실행된다는 것이다.)
엔드포인트
엔드포인트는 간단히 말하면 클라이언트와 서버가 상호작용할 수 있는 url이다.
처음 서버를 접했을 때 도대체 프론트와 백이 어떻게 정보를 주고 받을 수 있는지 이해가 가지 않았는데, 엔드포인트는 둘을 이어주는 오작교 역할을 한다.
@app.route('/send_url', methods=['POST'])
def send_url():
# url을 받아옴
data = request.get_json()
current_url = data.get('url')
# url에서 필요한 정보를 추출
user_id = extract_user_id_from_url(current_url)
problem_id = extract_problem_id_from_url(current_url)
# 터미널에 데이터 출력
print(f'Received URL: {current_url}')
print(f'User ID: {user_id}')
print(f'Problem ID: {problem_id}')
problems = get_similar_problem(problem_id)
return jsonify(message=f'{problems}')
get_similar_problem 함수에 추천시스템 모델을 정의해놨고, 이곳에 문제 id를 url로부터 추출하여 건냈다.
그렇게 받아온 추천 문제를 제이슨형식으로 return했다.
여기까지는 수월하게 됐지만 문제가 생겼다.
플라스크가 응답을 하기전에 자바스크립트가 렌더링을 해버리는 것이다.
플라스크는 응답하기 이전이므로 응답값은 undefined가 되어버려서 추천 문제는 undefined가, 문제 url은 404에러가 발생한다. (추천 문제를 클릭하면 그 문제로 이동할 수 있게 했다.)
따라서 자바스크립트는 플라스크가 응답을 할 때까지 기다려야 한다.
이를 위해서는 비동기 방식으로 await을 해야햔다.
. . . const fetchData = async () => { try { // 서버에 POST 요청을 보내고 데이터를 가져옴 const response = await fetch('http://127.0.0.1:8080/send_url', { method: 'POST', body: JSON.stringify({ url: window.location.href }), headers: { 'Content-Type': 'application/json' } }); . . .