Skip to content

Instantly share code, notes, and snippets.

@jays1204
Last active September 24, 2023 04:50
Show Gist options
  • Star 50 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save jays1204/703297eb0da1facdc454 to your computer and use it in GitHub Desktop.
Save jays1204/703297eb0da1facdc454 to your computer and use it in GitHub Desktop.
Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까?

요즘의 Request

RestFul API를 사용하며 json을 많이 사용하게 됨에 따라 요즈음의 request의 Content-Type은 대부분이 application/json인 것이 많다.

아니면 파일 첨부를 위해 multipart/*를 사용한다. application/x-www-form-urlencoded는 form에서 default로 사용되는 것 이외에는 사실 잘 사용하지 않는 편으로 보인다.

요새 자주 사용하지 않지만, 하지만 여전히 application/x-www-form-urlencoded를 사용하는 경우가 존재한다.

Content-Type이 다름에 따라 뭐가 달라지겠느냐 하겠지만 다른 점이 분명히 있다.

application/json이 {key:value}의 형태로 전송되며 application/x-www-form-urlencoded가 key-value&key=value...의 형태로 전송되는것 외에도 데이터의 압축 여부 등의 size 차이등(file을 전송할 때 왜 multipart/formed-data를 사용할까? 다른 Content-Type을 사용하면 파일 전송이 안될까? 인코딩후 사이즈 차이다.)의 차이점이 존재한다.

그중 하나의 차이점으로 POST로 보내며 Content-Type이 application/x-www-form-urlencoded의 body encoding을 생략할 시 나타나는 문제점이다.

우선 Browser에서는 알아서 body를 인코딩해서 보내주는 것으로 보인다. (많은 브라우저가 W3를 충실히 따르는 것 같다.)

문제는 개발자가 직접 request를 코드로 작성할 떄이다.

이를 위해 우선 Content-Type에 대해 간단하게 알아보자.

Content Type

우선 Content-Type에 대해 알아보자.

HTTP Header에 쓰이는 Content-Type이란 무엇일까?

request에 실어 보내는 데이터(body)의 type의 정보를 표현한다.

Text타입으로는 text/css, text/javascript, text/html, text/plain등이 있다.

html문서에 type을 명시할 때 text/javascript 혹은 text/css를 이미 써봤으리라 생각한다.

File을 실어보내기 위한 타입으로는 multipart/formed-data가 있다.

그리고 Application 타입으로 application/json, application/x-www-form-urlencode가 있다.

Content Type은 Request에 실어 보내는 data의 type에 따라 적절하게 선택을 해주면 된다.

이쯤에서 Content Type의 설명은 간략하게 된거 같다. 더 자세하게 내용을 알고싶다면 W3의 다음 페이지를 참고하기 바란다. http://www.w3.org/Protocols/rfc1341/4_Content-Type.html

그래서 결론이 뭔데?

다시 본론으로 돌아와 보자. application/x-www-form-urlencoded를 사용할 때 body를 encoding 하는 것이 필수인가? 그에 대한 답은 W3에 있는 문서에 나와 있다.

  • application/x-www-form-urlencoded
    This is the default content type. Forms submitted with this content type must be encoded as follows: *
  1. Control names and values are escaped. Space characters are replaced by +', and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by %HH', a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., `%0D%0A').
  2. The control names/values are listed in the order they appear in the document. The name is separated from the value by =' and name/value pairs are separated from each other by &'

encoding을 해야 한다고 나온다. 브라우저에서는 아마 대부분 기본적으로 해당 content-type에 대해 자동으로 encoding하도록 구현을 해놓았을 것이다.

따라서 우리가 주의해야 할 것은 하나다. application logic에서 applcation/x-www-form-urlencoded를 사용할 경우 body 인코딩이 해당 framework 혹은 library에서 자동으로 되는지 확인 후 안되면 해줘야한다.

아래와 같은 경우로 코드를 만들경우에는 조심해야 한다.

HttpClient client = new HttpClient();
  //blah blah...
	PostMethod method = new PostMethod("targetUrl");
	method.getParams().setContentCharset(charSet);
	method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
	method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset="+ charSet);

한가지로 예제로 node.js의 request 라이브러리는 해당 Content-Type에 대해 qs.stringify로 url인코딩하도록 이미 내부에 구현이 되어있다.

Request.prototype.form = function (form) {
  if (form) {
    this.setHeader('content-type', 'application/x-www-form-urlencoded; charset=utf-8')
    this.body = qs.stringify(form).toString('utf8')
  return this 
}
  // create form-data object
  this._form = new FormData()
  return this._form
}
@rico345100
Copy link

rico345100 commented Oct 17, 2016

맨 마지막 내용 때문인지 모르겠습니다만 content-type을 application/json으로 변경해도 x-www-form-urlencoded로만 전달되더군요..; 해결책은 form 옵션 대신 json이라는 옵션으로 전달해야 합니다.

@choy1379
Copy link

웹프로그래밍 공부중이라 도움이 많이 됬습니다 감사합니다

@jays1204
Copy link
Author

@rico345100 node.js의 request라이브러리를 말씀하신 거라면 request에는 form, json, body등의 옵션이 있는데 각각 선택에 따라 content-type이 설정됩니다.
form의 경우에는 말 그대로 x-www-form-urlencoded가, json은 application/json이 설정됩니다.

@jays1204
Copy link
Author

@choy1379 감사합니다 👍

@DublinCity
Copy link

2주 전에 읽을 때에는 까막눈이었는데 ajax 를 구현하면서 보니 이제야 조금식 이해가 가는군요
잘 정리된 글 읽게 해주셔서 감사합니다.

@Jae-kwang
Copy link

클라이언트에서 post 전송시 form submit와 ajax를 통한 post시 어떠한 차이가 있는지에 대해 찾아보던 중이었는데 잘 읽었습니다~ 감사합니다!

@jays1204
Copy link
Author

@Jae-kwang form submit과 ajax를 통한 post의 차이보다 http header의 content-type에 따른 차이라고 보시면 될거 같습니다. 감사합니다.

@kdyhkdy
Copy link

kdyhkdy commented May 11, 2019

x-www-form-urlencode 방식을 쓸때와 json방식을 쓸때 차이가 뭔가요?? 단지 인코딩이 자동으로 되는지 안되는지 차이인가요?? 여기서 인코딩은 암호화와는 다른 의미인거죠??
x-www-form-urlencode 를 요즘은 사용을 거의 안한다고 하는데 이유가 뭔가요??

그리고 위에 댓글중 json으로 호출 하도록 했음에도 x-www-form-urlenco 로 호출이 되는건 어떤부분을 수정해야하나요?? 화면 호출부분에서 호출 설정을 변경해주어야하나요??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment