기록

ajax, form 전송, formData 본문

TIL*

ajax, form 전송, formData

mnmhbbb 2022. 1. 23. 17:34

1.
ajax 시작하기
(https://developer.mozilla.org/ko/docs/Web/Guide/AJAX/Getting_Started)
ajax란?
Asynchronous JavaScript And XML
=비동기 자바스크립트와 XML
=서버와 통신하기 위해 XMLHttpRequest 객체를 사용하는 것
JSON, XML, HTML, 일반 텍스트 형식 등을 포함한 다양한 포맷을 주고 받을 수 있다.
AJAX의 강력한 특징은 페이지 전체를 리프레쉬 하지 않고서도 수행 되는 "비동기성"
이러한 비동기성을 통해 사용자의 Event가 있으면 전체 페이지가 아닌 일부분만을 업데이트 할 수 있게 함
정리하면, ajax를 사용하면 페이지 새로고침없이 서버에 데이터를 요청하고 데이터를 받아서 작업을 수행할 수 있다.

JavaScript를 이용하여 서버로 보내는 HTTP request를 만들기 위해서는 그에 맞는 기능을 제공하는 Object의 인스턴스가 필요함

httpRequest = new XMLHttpRequest();

이때 HTTP Request 객체의 open(), send() 메서드를 사용하여 요청할 수 있으며
각 메서드의 파라미터에 다음 정보를 담아야 한다.

httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send(null);

첫번째 파라미터는 HTTP 요구 방식(request method). 이 파라미터는 HTTP 표준에 따라 모두 대문자로 표기해야 함
두번째 파라미터는 요구하고자 하는 URL
세번째 파라미터는 생략 가능하여, 요청이 비동기식(Asynchronous)으로 수행될 지를 결정함.
만약 이 파라미터가 
true(기본값) 으로 설정된 경우에는 자바스크립트 함수가 지속적으로 수행될 수 있어 서버로부터 응답을 받기 전에도 유저와 페이지의 상호작용이 계속 진행되며 이것이 AJAX 의 첫번째 A (Asynchronous : 비동기성) 입니다.

send()에는 POST 방식으로 요구한 경우, 서버로 보내고 싶은 어떠한 데이터라도 가능한데, 데이터는 서버에서 쉽게 parse할 수 있는 형식(format)이어야 함. multipart/form-data*, JSON, XML, SOAP 등과 같은 다른 형식(format)도 가능함.
(*multipart/form-data는 formData 형식)

이렇게 서버에 요청을 보내기 전에 꼭 해야 할 일이 있는데 바로 서버의 응답을 받았을 때 어떤 동작을 수행할지이다.
이때 서버의 응답 상태 코드를 검사하여 다른 동작을 처리할 수 있다.
HTTP 응답 상태 코드(https://developer.mozilla.org/ko/docs/Web/HTTP/Status)

if (httpRequest.status === 200) {
    // 이상 없음!
} else {
    // 요구를 처리하는 과정에서 문제가 발생되었음
    // 예를 들어 응답 상태 코드는 404 (Not Found) 이거나
    // 혹은 500 (Internal Server Error) 이 될 수 있음
}

 

 

2.
form(https://developer.mozilla.org/ko/docs/Web/HTML/Element/form)

HTML <form> 요소는 정보를 제출하기 위한 대화형 컨트롤을 포함하는 문서 구획을 나타내며 각 속성에 대한 특징은 다음과 같다.

action
양식 데이터를 처리할 프로그램의 URI

enctype
method 특성이 post인 경우, enctype은 양식 제출 시 데이터의 MIME* 유형을 나타냄
폼에 입력된 데이터가 서버로 제출될 때 해당 데이터가 인코딩되는 방법을 의미함

  • application/x-www-form-urlencoded: 기본값.
    모든 문자들을 서버로 보내기 전에 인코딩됨을 명시한다.
  • multipart/form-data: <input type="file">이 존재하는 경우 사용
    모든 문자를 인코딩하지 않음을 명시하며, 파일을 서버에 전송할 때 사용함
  • text/plain: HTML 5에서 디버깅 용으로 추가된 값.
    공백 문자(space)는 + 기호로 변환되고 나머지 문자는 모두 인코딩되지 않음

추가 참조:(https://velog.io/@shin6403/HTTP-multipartform-data-%EB%9E%80)

+) MIME Type(https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types)

클라이언트에게 전송된 문서의 다양성을 알려주기 위한 메커니즘입니다: 웹에서 파일의 확장자는 별  의미가 없습니다. 그러므로, 각 문서와 함께 올바른 MIME 타입을 전송하도록, 서버가 정확히 설정하는 것이 중요합니다. 브라우저들은 리소스를 내려받았을 때 해야 할 기본 동작이 무엇인지를 결정하기 위해 대게 MIME 타입을 사용합니다.
type/subtype

MIME 타입의 구조는 위와 같다. 
type은 카테고리를 나타내며 개별 혹은 멀티파트 타입이 될 수 있다.
subtype은 각각의 타입

1) 개별 타입은 문서의 카테고리를 나타내며 text, image, audio, video, application(모든 종류의 이진 데이터를 나타냄)이 있다.

특정 서브타입이 없는 텍스트 문서들에 대해서는 text/plain가 사용되어야 합니다. 특정 혹은 알려진 서브타입이 없는 이진 문서에 대해서는 유사하게, application/octet-stream이 사용되어야 합니다.

2) 멀티파트 타입

멀티파트 타입은 일반적으로 다른 MIME 타입들을 지닌 개별적인 파트들로 나누어지는 문서의 카테고리를 가리킵니다. 
즉 이 타입은 합성된 문서를 나타내는 방법입니다. HTML Forms과 POST 메서드의 관계 속에서 사용되는 multipart/form-data 그리고 전체 문서의 하위 집합만 전송하기 위한 206 Partial Content 상태 메시지와 함께 사용되는 multipart/byteranges를 제외하고는, HTTP가 멀티파트 문서를 다룰 수 있는 특정한 방법은 존재하지 않습니다: 메시지는 브라우저에 간단히 전달됩니다 (문서를 인라인에 어떻게 디스플레이할지 모르기에, '다른 이름으로 저장' 윈도우를 제시할 겁니다)
multipart/form-data은 브라우저에서 서버로 HTML Form의 내용을 전송 시 사용할 수 있습니다. 멀티 파트 문서 형식으로써, 경계(이중 대시 '--' 로 시작되는 문자열)로 구분되어지는 다른 파트들로 구성됩니다. 각 파트는 그 자체로 개체이며 자신만의 HTTP 헤더를 가지는데, 파일 업로드 필드를 위한 헤더로는 Content-Disposition, 그리고 가장 일반적인 것 중 하나인 Content-Type이 있습니다(Content-Length은 경계선이 구분자로 사용되므로 무시됩니다).

method
양식을 제출할 때 사용할 HTTP 메서드

  • get: GET 메서드. 양식 데이터를 action URL과 ? 구분자 뒤에 이어 붙여서 전송
  • post: POST 메서드. 양식 데이터를 요청 본문으로 전송

name
양식의 이름. HTML4부터 지원 중단되어 id로 사용할 것

 

form이 submit이 되면 form안에 있는 데이터가 서버로 전송된다.
이때 이런 데이터들은 HTTP Request 형태로 서버로 전송된다. 파일 업로드의 원리는 HTTP Request가 가지고 있는데,

  • HTTP Request는 Body에 클라이언트가 전송하려고 하는 데이터를 넣을 수 있다.
  • Body에 들어가는 데이터의 타입을 HTTP Header에 명시해 줌으로써 서버가 타입에 따라 알맞게 처리하게 한다.
  • Body의 타입을 명시하는 Header가 Content-type이다.

일반적인 form의 submit에 의한 데이터들의 Content-type application/x-www-form-urlencoded 이지만, 두 종류의 데이터가 하나의 HTTP Request Body에 들어가야 할 때는  Body에서 이 2 종류의 데이터를 구분에서 넣어주는 방법도 필요해졌다.
그래서 등장하는 것이 multipart 타입 multipart/form-data를 사용한다.

출처: https://velog.io/@shin6403/HTTP-multipartform-data-%EB%9E%80

 

3. form 전송하기

1)form 태그를 이용하여 동기식으로 전송하기
2)form 하위에 담긴 데이터를 ajax를 이용하여 동기식으로 전송하기

jquery serialize(), serializeArray() 메서드를 사용하면 form 하위에 담겨있는 값들을 한 번에 담아서 간편하게 전송할 수 있다.
jquery를 사용하지 않을 경우 formData()를 사용할 수 있다.

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

 

4. 
formData(https://developer.mozilla.org/ko/docs/Web/API/FormData)

form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공합니다. 또한 XMLHttpRequest.send() 메서드를 사용하여 쉽게 전송할 수 있습니다.
인코딩 타입이 "multipart/form-data"로 설정된 경우, form에서 사용하는 것과 동일한 포맷을 사용해야 합니다.
간단한 GET 전송을 사용하는 경우에는 <form>이 수행하는 방식으로 쿼리 매개 변수를 생성할 수 있습니다. 이 경우  URLSearchParams 생성자에 직접 전달할 수 있습니다.

formData를 사용하는 결정적인 이유는 input type="file"의 값을 전달하기 위함이다.
form태그의 enctype은 데이터의 MIME 유형을 나타낸다고 했고 multipart/form-data은 input type="file"인 경우 사용한다고 했다. 

바이너리파일을 텍스트파일로 인코딩이 필요하다.

binary(바이너리)파일=이진 파일
텍스트 파일이 아닌 컴퓨터 파일로, 컴퓨터 저장과 처리 목적으로 이진 형식으로 인코딩된 데이터를 포함한다.
출처:(https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%8C%8C%EC%9D%BC)

 

HTTP 메시지(https://developer.mozilla.org/ko/docs/Web/HTTP/Messages)
HTTP 메시지는 ASCII*로 인코딩된 텍스트 정보이며 여러 줄로 되어 있습니다. HTTP 프로토콜 초기 버전과 HTTP/1.1에서는 클라이언트와 서버 사이의 연결을 통해 공개적으로 전달되었습니다. 이렇게 한 때 사람이 읽을 수 있었던 메시지는 HTTP/2에서는 최적화와 성능 향상을 위해 HTTP 프레임으로 나누어집니다.

HTTP/2의 이진 프레이밍 메커니즘(binary framing mechanism)은 사용 중인 API나 설정 파일 등을 변경하지 않아도 되도록 설계 되었기 때문에, 사용자가 보고 이해하기 쉽습니다.

HTTP 요청과 응답의 구조는 서로 닮았으며, 그 구조는 다음과 같습니다.

  1. 시작 줄(start-line)에는 실행되어야 할 요청, 또은 요청 수행에 대한 성공 또는 실패가 기록되어 있습니다. 이 줄은 항상 한 줄로 끝납니다.
  2. 옵션으로 HTTP 헤더 세트가 들어갑니다. 여기에는 요청에 대한 설명, 혹은 메시지 본문에 대한 설명이 들어갑니다.
  3. 요청에 대한 모든 메타 정보가 전송되었음을 알리는 빈 줄(blank line)이 삽입됩니다.
  4. 요청과 관련된 내용(HTML 폼 콘텐츠 등)이 옵션으로 들어가거나, 응답과 관련된 문서(document)가 들어갑니다. 본문의 존재 유무 및 크기는 첫 줄과 HTTP 헤더에 명시됩니다.

HTTP 메시지의 시작 줄과 HTTP 헤더를 묶어서 요청 헤드(head)라고 부르며, 이와 반대로 HTTP 메시지의 페이로드는 본문(body)이라고 합니다.

 

*ASCII
아스키는 영문 알파벳을 사용하는 대표적인 문자 인코딩

Comments