깊은바다거북
개발 공부 기록
깊은바다거북
전체 방문자
오늘
어제
  • 분류 전체보기 (219)
    • JAVA (9)
    • JavaScript (15)
    • 스파르타코딩클럽 (11)
      • [내일배움단] 웹개발 종합반 개발일지 (5)
      • [내일배움캠프] 프로젝트와 트러블 슈팅 (6)
    • SQL | NoSQL (4)
    • CS 등등 (0)
    • TIL | WIL (173)
    • 기타 에러 해결 (3)
    • 내 살 길 궁리 (4)

인기 글

최근 글

최근 댓글

태그

  • 재귀 함수
  • 자료 구조
  • TypeScript
  • 점화식(Recurrence Relation)
  • 자바스크립트 기초 문법
  • Backtracking(백트래킹)
  • BST(이진 탐색 트리)
  • 자잘한 에러 해결
  • BFS(너비우선탐색)
  • Binary Tree(이진 트리)
  • TIT (Today I Troubleshot)
  • Til
  • 01. 미니 프로젝트
  • 트러블 슈팅 Troubleshooting
  • leetcode-cli
  • 최대 힙(Max Heap)
  • POST / GET 요청
  • tree
  • Trie
  • Inorder Traversal(중위 순회)
  • 코딩테스트 연습문제
  • DFS(깊이우선탐색)
  • 시간 복잡도
  • 최소 힙(Min Heap)
  • 혼자 공부하는 자바스크립트
  • 팀 프로젝트
  • Preorder Traversal(전위 순회)
  • 프로그래머스
  • Linked List
  • Leetcode
hELLO · Designed By 정상우.
깊은바다거북

개발 공부 기록

스파르타코딩클럽/[내일배움캠프] 프로젝트와 트러블 슈팅

jsonify()는 뭘 어떻게 포장해서 프론트로 보내는가 ✔️

2022. 12. 3. 21:00

발단:

app.py에서 return jsonify(”쌩 메세지”)로 보내고, 프론트에서 success: function(response) { alert(response) } 해도 alert(response[’msg’]) 때와 똑같은 형식으로 잘 뜨는 것을 발견했다. 이유가 궁금했다.

  • response를 jsonify로 안 보내면 어떻게 되지?

    ⇒ jsonify()로 안 보내도 된다. 이 포스트에 연구해놓았다.

  • response를 jsonify로 잘 보내도, ‘키’값이 없는데 어떤식으로 저장돼서 보내지고 출력되는 거지?

    ⇒ 결론부터 말하면, jsonify()는 위치 인자를 그냥 나열하는 것(jsonify(”메세지1”, “메세지2”, …))과 키워드 인자쌍을 주는 방식(jsonify({”msg”: “메세지1”, “msg2”: “메세지2”})) 두 가지를 모두 소화한다. 반환하는 객체는 flask.wrappers.Response.

실험:

서버에서 jsonify를 여러 방식으로 주고:

@app.route("/api/comments", methods=["POST"])
def post_comment():
	...
	resp = jsonify("Comment added successfully!", msg2="Another message~")
  # resp = jsonify({'msg': "Comment added successfully!", 'msg2':"Another message~"})
  # resp = jsonify(msg="Comment added successfully!", msg2="Another message~")
	return resp

프론트에선 콘솔에 한번, alert 창으로 한 번 응답을 찍어 보았다:

function save_comment() {
	...
	$.ajax({
      type: 'POST',
      url: '/api/comments',
      data: {...},
      success: function (response) {
          console.log(response, typeof(response))
          alert(response)
      }
  })
}

결과:

서버에서: return jsonify(’메세지’) ⇒ 프론트 콘솔에서: 메세지, 타입은 string ⇒ 프론트 alert에서: 메세지

서버에서: return jsonify(’메세지1’, ‘메세지2’) ⇒ 프론트 콘솔에서: ['Comment added successfully!', 'Another message~'], 타입은 'object’ ⇒ 프론트 alert에서: Comment added successfully!,Another message~

서버에서: return jsonify({’msg’: ‘메세지’}) ⇒ 프론트 콘솔에서: {msg: '메세지'}, 타입은 'object’ ⇒ 프론트 alert에서: [object Object]

서버에서: return jsonify({’msg’: ‘메세지’, ‘msg2’: ‘메세지2’}) ⇒ 프론트 콘솔에서: {msg: 'Comment added successfully!', msg2: 'Another message~'}, 타입은 'object’ ⇒ 프론트 alert에서: [object Object]


jsonify()

flask.json def jsonify(*args: Any, **kwargs: Any) -> Response

positional arguments나 keyword arguments 둘 중 한 쪽만 제공해야 한다.

*args가 여러개 주어지면 list로 취급되고, **kwargs가 주어지면 딕셔너리로 취급된다. (파이썬 *args는 튜플로 취급되는 거 아녔어??) (아마 list로 ‘반환한다’는 얘기 같다. 이걸 자바스크립트쪽에서 받으면 배열이 되겠지)

반환값은 flask.wrappers.Response 객체. HTML mimetype (application/json mimetype.)이 함께 주어진다는 점이 Werkzeug의 response 객체와 다르다는데… mimetype이란?


MIME type

: Multipurpose Internet Mail Extensions.

: Media type.

: 즉 문서나 파일, 바이트모음의 본질과 형식을 일컬어주는 말. IETF's RFC 6838에 정의되어 있다고 한다.

예를 들어 HTML형태의 파일을 위해선 ‘text/html’타입을 지정해주고, jpeg형태의 파일을 위해서는 ‘image/jpeg’타입으로 지정해준다. 그러면 웹 브라우저가 웹 서버 쪽에서 HTTP로 보내온 파일을 어떤 식으로 출력해야할지 알 수 있게 된다.

‘application/json’은 JSON 형식을 특정하는 MIME type이다. 즉 jsonify가 반환하는 값은 flask의 response객체인데, ‘날 해석할 방법은 JSON이다’라는 MIME 타입 정보를 함께 실어 보낸다는 뜻이 되겠다.

결국 프론트에서 받는 response는:

*args에 인수 하나만 넣어 넘겨주면 jsonify된 결과는 순수 string타입이다.

*args에 인수 둘 이상을 넣어주면 jsonify된 결과는 ‘object’, 즉 파이썬 리스트에서 js 배열로 전달되는 듯 하다.

**kwargs에 키=값 형태로 넣어주면 ({’키’: ‘값’}의 형태도 괜찮음) jsonify된 결과는 ‘object’, 즉 파이썬 딕셔너리에서 js 객체 혹은 JSON객체로 전달되는 듯 하다.


결론:

즉 1. *args에 위치 인자들로 데이터를 넣어주는 방식을 쓰든지 :

// app.py
@app.route("/api/comments", methods=["POST"])
def post_comment():
	...
	return jsonify("Comment added successfully!", "Another message~")


// index.html
$.ajax({
      type: 'POST',
			url: '/api/comments',
      ...
      success: function (response) {
          alert(response[1]) // Another message~
      }
  })

  1. **kwargs에 키워드 인자들로 데이터를 넣어주는 방식을 쓰든지 :
// app.py
@app.route("/api/comments", methods=["POST"])
def post_comment():
	...
	// return jsonify(msg="Comment added successfully!", msg2="Another message~")
	return jsonify({'msg': "Comment added successfully!", 'msg2':"Another message~"})
		// 위아래 둘 다 가능.

// index.html
$.ajax({
      type: 'POST',
			url: '/api/comments',
      ...
      success: function (response) {
          alert(response['msg2']) // Another message~
      }
  })

둘 중 한 가지를 사용하면 되겠다.


+

*args 인수와 **kwargs 인수를 모두 줘봤다:

TypeError: app.json.response() takes either args or kwargs, not both 127.0.0.1 - - [28/Nov/2022 13:07:20] "POST /api/comments HTTP/1.1" 500 -

에러남. 예상되는 그대로의 메세지를 던진다.


Uploaded by N2T

    '스파르타코딩클럽/[내일배움캠프] 프로젝트와 트러블 슈팅' 카테고리의 다른 글
    • MongoDB의 ObjectId 최대한 간단하게 처리해서 프론트로 넘겨주기 ✔️
    • 비번 확인해서 삭제시키기 + 실패시 에러 메세지 띄우기 ✔️
    • HTML 스크립트 태그 내에서 제이쿼리 이벤트가 무시되는 에러 해결 ✔️
    • 01. 미니 프로젝트 - 팀 페이지를 만들 때
    깊은바다거북
    깊은바다거북

    티스토리툴바