정적 웹페이지 : 서버에 저장돼있는 html과 css를 보여주는 것
(ex : 회사소개, 포트폴리오 / 서비스가 한정적)
동적 웹페이지 : 상황에 따라서 서버에 저장돼있는 html에 데이터를 가공해서 보여주는 것
(ex : 블로그, 날씨 정보 / 보안에 취약함)
CSR : Js에 데이터를 보낸 후 클라이언트에서 html을 받는 방법
SSR : html에 미리 구축된 데이터를 받는 방법
CSR + SSR : Ajax
flask의 templates 폴더에 두 html을 create하고 서로의 페이지로 이동할 수 있다.
경로는 "/"부터 입력하면 된다!
아래는 sub page에서 main page로 이동하는 코드다.
<button onclick="window.location.href='/'">메인페이지로 이동</button>
Jinja에서는 {{}}로 String 사이에 데이터를 넣을 수 있다.
app.py 에서는 아래와 같이,
@app.route('/') def main(): myname = "World" return render_template("index.html", name=myname)
index.html에서는 아래와 같이 입력한다.
<h3>Hello, {{name}}!</h3>
Jinja는 html에서 다양한 구문을 사용할 수 있으며, html에 다른 html을 끼워넣을 수도 있다.
html에서가 아닌 서버에서 data를 받아오도록 app.py에 다음 코드를 작성한다.
@app.route('/detail') def detail(): r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99') response = r.json() rows = response['RealtimeCityAir']['row'] return render_template("detail.html", rows=rows)
이후 html에 다음 코드를 작성하는데, Jinja templates : {% %}를 사용하면 파이썬처럼 구문을 작성할 수 있다.
단, {% end~ %}가 꼭 필요하다.
|int는 변수값을 정수로 바꿔준다.
<ul id="gu_list"> {% for row in rows %} {% set gu_name = row["MSRSTE_NM"] %} {% set gu_mise = row["IDEX_MVL"] %} {% if gu_mise >= 60 %} <li>{{ gu_name }} : {{ gu_mise|int }}</li> {% endif %} {% endfor %} </ul>
참고로, Jinja에서 dictionary 형태를 가져올 때 ['text'] 대신 .text를 쓸 수 있다.
if문에서는 !=None을 써야될 경우, if text만 써도 자동처리된다.
또, html의 태그를 그대로 써야될 경우 |safe를 사용한다.
html에서 태그나 문자열을 real string으로 사용하고자 한다면, |tojson을 사용한다.
만약, 아스키코드 종류가 아닌 다른 특수문자를 인식하지 못할 경우 다음과 같이 무시 처리한다.
.encode('ascii', 'ignore').decode('utf-8')
app.py에서 request를 이용해 주소 뒤에 '?word_give=text'를 작성하면, text를 받아온다.
word_receive = request.args.get("word_give")
그런데, 다음과 같이 코드를 입력하고 주소 뒤에 '/text'를 작성해도 역시 text를 받아온다.
@app.route('/detail/<keyword>') def detail(keyword):
OwlBot의 OpenAPI를 이용하기 위해서 Token Code를 받은 후 다음과 같이 app.py에 쓴다.
@app.route('/detail/<keyword>') def detail(keyword): r = requests.get(f"https://owlbot.info/api/v4/dictionary/{keyword}", headers={"Authorization": "Token [CODE]"}) result = r.json() print(result) return render_template("detail.html", word=keyword)
API를 불러오는 ajax 코드는 다음과 같다.
일단 여기서는 받아온 data가 공백이므로 let word = ""로 설정한다.
$.ajax({ type: "GET", url: `https://owlbot.info/api/v4/dictionary/${word}`, beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Token [CODE]"); }, data: {}, error: function (xhr, status, error) { alert("ERROR"); }, success: function (response) { console.log(response) } })
app.py로부터 페이지 정보 (keyword)를 word로 받아와서 사전 API를 거쳐 얻는다.
pronunciation이 없을 경우 받아오지 않는다.
$('#word').text(response['word']) if (response['pronunciation'] == null) { $('#pronunciation').text('') } else { $('#pronunciation').text(`/${response['pronunciation']}/`) }
app.py에서 먼저 POST 코드를 작성한다.
@app.route('/api/save_word', methods=['POST']) def save_word(): # 단어 저장하기 word_receive = request.form['word_give'] definition_receive = request.form['definition_give'] doc = {'word': word_receive, 'definition': definition_receive} db.words.insert_one(doc) return jsonify({'result': 'success', 'msg': f'단어 {word_receive} 저장'})
이후 detail.html에서 다음을 작성한다.
html의 word_give와 definition_give에서 받은 form을 db에 저장한다.
function save_word() { $.ajax({ type: "POST", url: `/api/save_word`, data: { word_give: '{{ word }}', definition_give: '{{ result.definitions[0].definition }}' }, success: function (response) { alert(response["msg"]) window.location.href = '/detail/{{ word }}?status_give=old' } }); }
해당 페이지에서 save_word 함수를 불러오면 status_give를 old로 바꿔준다.
style이 담긴 CSS파일을 static에 새로 생성하여 html에서 불러올 수 있다.
두 페이지 이상에서 똑같은 style요소가 있을 때 사용하면 좋다.
css 파일을 사용할 html에서 다음 코드를 적용할 필요가 있다.
<link href='{{ url_for("static", filename="mystyle.css") }}' rel="stylesheet">
이후 html에 style에 적용한 class를 body에 써주기만 하면 적용이 된다.
script의 list에 새로운 ingredients를 넣을 때는 .push를 사용한다.
word_list.push(words[i]['word'])
list에 ingredients가 포함되는지를 판별할 때는 .includes를 사용한다.
word_list.includes(word)
class를 적용할 때는 .addClass를 사용한다.
$(`#word-${word}`).addClass('highlight')
같은 태그 안의 siblings 요소에 대해서 불러올 때는 .siblings를 사용한다.
$(`#word-${word}`).siblings()
대소문자 상관없이 모두 소문자로 바꿀 때는 .toLowerCase를 사용한다.
$('#input-word').val().toLowerCase()
만약, 사전에 없는 단어를 입력한 경우에는 오류를 내뿜는다.
따라서, .status_code를 appl.py에 입력해줌으로써 오류를 방지한다.
200의 의미는 api에서 가져올 데이터가 존재한다는 뜻이다.
if r.status_code != 200: return redirect('/') //또는 redirect(url_for('main'))