web
GET방식 POST방식
teestory
2011. 2. 22. 19:27
다음의 문서가 http://my.netian.com/~webtech/index.html이라고 할때,
<FORM METHOD=GET ACTION="cgi-bin/getproc.cgi">
이름 : <INPUT TYPE=text SIZE=20 NAME=login VALUE=" "><br>
나이 : <INPUT TYPE=text SIZE=5 NAME=age VALUE=" "><br>
성별 : <INPUT TYPE=radio NAME=sex VALUE=male> male
<INPUT TYPE=radio NAME=sex VALUE=female>female<br>
학교 : <SELECT NAME=school>
<OPTION VALUE="[WEB TECH]" CHECKED>WEB TECH
<OPTION VALUE="[WEB TOP]" CHECKED>WEB TOP
</SELECT>
<HR SIZE=2>
<INPUT TYPE=submit VALUE="등 록"><INPUT TYPE=reset VALUE="지우기">
</FORM>
이러한 폼 문에서 사용자가 이름으로 "권순형", 나이는 "25", 성별은 "male", 학교는 "[WEB TECH]"를 선택하였다고 하면, URL인코딩되기 전의 문자열 형태는 아래와 같다.
name=권순형&age=25&sex=male&school=[WEB TECH]
이러한 문자열의 URL인코딩 형태는
name=권순형&age=25&sex=male&school=%5BWEB+TECH%5D
가 되며 다음과 같은 형식으로 서버측에 전달된다.
/~webtech/cgi-bin/getproc.cgi?name=권순형&age=25&sex=male&school=%5BWBE+TECH%5D
CGI 프로그램의 이름 다음에 "?"가 오고, 그 다음에 폼 문에서 입력된 내용들이 이어진다. 이렇게 전송된 문자열에 대해 서버는 이 프로그램이 CGI 프로그램임을 탐지하고, "?"앞의 내용은 서버측의 환경변수인 PATH_INFO에 저장하고, "?"이하는 QUERY_STRING에 저장한다. 이와 같은 방식이 GET 메소드에 의한 데이터 전달이다.
그러나, 이러한 GET 메소드는 문자열을 저장할 수 있는 QUERY_STRING의 길이 제한으로 인해 많은 name=value 쌍을 서버측에 전달하는 것은 그리 효과적이 방법이 아니다. 이런 문제를 해결하기 위한 방법으로 표준 입력(standard input)을 사용하는 POST메소드가 널리 사용되고 있다. 표준 입력이라는 파일을 사용함으로써 문자열의 길이 제한 문제가 없어졌으므로, CGI 처리가 한결 편리해졌다. POST 메소드는 사용자의 요구 사항들을 표준 입력을 통해서 받는다는 점을 제외하고는 처리 과정은 GET 메소드와 동일하다.
3.2 서버측의 데이터 디코딩
다음으로, 클라이언트로부터 전달된 폼 양식을 서버에서 디코딩하는 과정이 필요하다. 이때 GET 메소드에 의해 전달된 데이터 디코딩과 POST 메소드에 의한 데이터 디코딩이 다르다. 이와 같은 일들을 하는 함수들은 util.c에 포함되어 있으므로 CGI 프로그램 작성시에는 util.c를 함께 컴파일하여 사용한다.
(1) GET 메소드에 의해 전달된 데이터 디코딩
GET 메소드에 의해 얻어진 데이터들은 환경변수 QUERY_STRING에 저장되어 있다. 이러한 데이터들은 name=value의 쌍으로 얻어지는데, 인코딩된 문자들을 인코딩과는 반대로 "+"는 공백으로, "%5B"는 "["등으로 바꾸어 주어야 한다. QUERY_STRING에 저장된 문자열에 대해서 URL디코딩 과정을 거친 후, name=value의 분리 작업을 실행한다. name=value는 문자열에서 "&"으로 구분되어 있으므로, 문자열에서 `&'가 나타날 때까지 한 문자씩 복사한 후, `&'가 나타나면 그 때까지 복사한 문자열을 하나의 name=value쌍으로 저장한다. QUERY_STRING에 저장된 문자열 전체에 대해서 이러한 과정을 거친 후 최종적으로 name=value의 쌍들을 구하게 된다. 각각이 name=value를 name과 value로 분리하고, CGI프로그램에서 name에 대한 value 값을 처리하도록 프로그램을 작성하면 된다.
printf("Content-type:text/html\n\n");
cl = getenv("QUERY_STRING");
if(cl==NULL){
printf("No query information to
decode. \n");
exit(1);
}
for(x=0; cl[0]!='\0';x++){
m=x;
getword(entries[x].val,cl,'&');
plustospace(entries[x].val);
unescape_url(entries[x].val);
getword(entries[x].name, entries[x].val, '=');
}
n_entries=x;
printf("Content-type:text/html\n\n");
cl=atoi(getenv("CONTENT_LENGTH"));
for(x=0; cl && (!feof(stdin)); x++){
m=x;
entries[x].val=fmakeword(stdin,'&',&cl);
plustospace(entries[x].val);
unescape_url(entries[x].val);
entries[x].name=makeword(entries[x].val, '=');
}
n_entries=x;
(2) POST
POST의 경우는 name=value쌍의 디코딩 과정은 GET 메소드와 동일하지만, 폼 문에서 입력된 문자열을 GET메소드에서 QUERY_STRING이라는 환경 변수에서 얻는 방법과는 달리, 표준 입력으로 얻는다. 따라서 파일을 다루는 모듈이 필요하다. printf("Content-type:text/html\n\n");
cl = getenv("QUERY_STRING");
if(cl==NULL){
printf("No query information to decode. \n");
exit(1);
}
for(x=0; cl[0]!='\0';x++){
m=x;
getword(entries[x].val,cl,'&');
plustospace(entries[x].val);
unescape_url(entries[x].val);
getword(entries[x].name, entries[x].val, '=');
}
n_entries=x;
< GET 메소드의 입력 데이터 받기 >
printf("Content-type:text/html\n\n");
cl=atoi(getenv("CONTENT_LENGTH"));
for(x=0; cl && (!feof(stdin)); x++){
m=x;
entries[x].val=fmakeword(stdin,'&',&cl);
plustospace(entries[x].val);
unescape_url(entries[x].val);
entries[x].name=makeword(entries[x].val, '=');
}
n_entries=x;
<POST 메소드의 입력 데이터 받기>
get 이냐 post냐 ? 아마도 cgi 초보자에게 있어선 가장 혼동되는 문제가 아닐까 생각합니다.
GET 메소드와 POST 메솓드는 단순히 환경변수로 받느냐, 표준 입출력으로 받느냐 하는 문제를
떠나서 실제 사용할 때에는 많은 차이를 보입니다.. GET 메소드와 POST메소드의 차이를 보다
정확히 알아 봅시다.
우선 GET 메소드는 QUERY STRING을 받아들이는 환경변수의 최대 크기에 따라 처리할수
있는 변수의 최대 크기가 제한됩니다. 다음은 get_method 함수 내의 일부분입니다.
char c12[500];
strcpy(c12,getenv("QUERY_STRING"));
위의 변수에서 보면, 쿼리의 크기가 제한이 되어 있습니다.
이에 비해 post 메소드는 표준 입출력으로 입력을 받으므로 최대 크기에 제한이 없습니다.
실제 활용에 있어서 최대 크기에 제한을 두고 싶지 않은 경우는 어떤경우 일까?
성명이나 전화번호 같은 변수들은 길어봐야 20자 정도가 될것이지만..
방명록의 본문 내용을 보낸다든지.. BBS에서 본문 내용을 보내는 경우
데이터베이스에 장문의 텍스트를 입력하는 경우라면 GET 메소드의 크기 제한이
퍽 성가신 문제가 될겁니다...
보안의 문제에선, GET 메소드는 ISINDEX 방식과 동일하게 FORM문으로 받은
데이터를 URL 뒤에 붙이는 다음과 같은 형태로 전송합니다.
HTTP://www.jointclub.net/cgi-bin/aaa.cgi?name=조인트&address=서울
이렇게 get메소드로 데이터를 전송하는 경우에 사용자는 브라우저의 location 부분을
에디팅함으로써 cgi 모듈에 전해지는 데이터를 조작할수 있습니다.
post 또한 마찬가지 일수 있지만.. get 보다는 약간 접근이 어렵다고 생각한다..
<form action=/cgi-src/test.cgi METHOD=POST> 성명:<INPUT TYPE=TEXT NAME=NAME SIZE=20><BR> 주소:<INPUT TYPE=TEXT NAME=ADDRESS SIZE=40><P> <INPUT TYPE="submit" VALUE="입력"> </FORM> Get Method 라면 어떨까? 물론 다음과 같은 예가 될 것이다... <form action=/cgi-src/test.cgi METHOD=GET> 성명:<INPUT TYPE=TEXT NAME=NAME SIZE=20><BR> 주소:<INPUT TYPE=TEXT NAME=ADDRESS SIZE=40><P> <INPUT TYPE="submit" VALUE="입력"> </form>
GET 나 POST나 사용자로부터 입력받을 경우는 FORM문을 사용해야 합니다.
GET 나 POST나 혼용할수 있습니다.
GET 방식 :
example.php?var1=value1&var2=value2 와 같은 방식입니다. 일반적인 HTTP 호출은 모두 GET 방식으로 이루어집니다. (변수 넘기지 않는 일반 호출도 GET 입니다) GET 이라는 의미 그대로, 그 파일을 그대로 가져오는겁니다. 물론, PHP라면 변수를 받아서 조작이 가능하지요. 사용이 간편하다는 장점이 있습니다. 단점은, 첫쨰, 길이 제한이 있습니다. 넘길 수 있는건 http:// 부터 시작해서, 최대 255자입니다. (변수부분만 255자가 아닙니다) 두번째, 넘어가는 변수가 주소줄에 그대로 노출됩니다. 다른사람에게 보여줘서는 안되는 것을 넘기면 유출될 위험이 크지요. (예: 패스워드 등)
: POST 방식 :
일반적으로 HTML의 FORM을 이용해서 넘기는 방식입니다. (FORM 태그에서 method="POST"로 지정하는게 POST 방식을 이용하라는 의미입니다. - 지정 안하면 GET으로 넘어가지요) 이 방식은 서버에 값을 넘기기 위해 만들어진 방식입니다. GET 방식과 다르게 밖으로 보여지지 않으며, 길이에도 제한이 없습니다(규격상으로는).
get 방식 예제 - asptest6.htm
<HTML>
<HEAD>
<TITLE> get 방식 예제 </TITLE>
</HEAD>
<BODY>
<CENTER>
<FORM NAME="form1" ACTION="get_meth_view.asp" METHOD="get">
이 름 : <INPUT TYPE="text" NAME="uname">
메 일 : <INPUT TYPE="text" NAME="mail">
<P></P>
<INPUT TYPE="submit" VALUE="전송">
<INPUT TYPE="reset" VALUE="다시">
</FORM>
</CENTER>
</BODY>
</HTML>
테스트 후 브라우저의 주소박스에 보여지는 URL은 다음과 같습니다.
http://localhost/object_asp/get_meth_view.asp?uname=seong+gigoo&mail=midibest@orgio.net
<A> 태그를 이용해서도 같은 결과을 얻을 수 있습니다.
<A HREF="get_meth_view.asp?uname=seong+gigoo&mail=midibest@orgio.net"> 누르세요 </A>
이제 서버로 보내어진 정보를 추출하는 방법에 대해서 알아 보도록 하겠습니다.
파일명 : get_meth_view.asp
<%@ LANGUAGE=VBScript%>
<HTML>
<HEAD>
<TITLE> 예제 6 </TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>다음의 정보를 입력하셨습니다.</H1>
이 름 = <B><%=Request.QueryString("uname")%></B>
메 일 = <B><%=Request.QueryString("mail")%></B>
</CENTER>
</BODY>
</HTML>
지금 까지의 예가 바로 GET 방식입니다.
이 방식은 위에 보셨듯이 서버로 정보를 보내는 방법에는
<FORM> 태그의 method 속성을 'get'으로 하는 방법과
<A> 태그를 이용하는 방법등이 있습니다.
그리고 정보를 추출할 때는 위와 같이 Request 객체의 QueryString 컬렉션을 이용하면됩니다.
자세한 것은 Request 객체를 공부하시면됩니다.
POST 방식 예제
파일명 : post_meth_vtest.htm
<HTML>
<HEAD>
<TITLE> POST 방식 예제 </TITLE>
</HEAD>
<BODY>
<CENTER>
<FORM NAME="form1" ACTION="post_meth_view.asp" METHOD="post">
이 름 : <INPUT TYPE="text" NAME="uname">
<BR>
메 일 : <INPUT TYPE="text" NAME="mail">
<BR><BR>
<INPUT TYPE="submit" VALUE="전송">
<INPUT TYPE="reset" VALUE="다시">
</FORM>
</CENTER>
</BODY>
</HTML>
서버로 보내어진 정보를 추출하는 방법에 대해서 알아 보도록 하겠습니다.
파일명 : post_meth_view.asp
<%@ LANGUAGE=VBScript%>
<HTML>
<HEAD>
<TITLE> POST 방식 예제 출력 소스 </TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>다음의 정보를 입력하셨습니다.</H1>
이 름 = <B><%=Request.Form("uname")%></B>
메 일 = <B><%=Request.Form("mail")%></B>
</CENTER>
</BODY>
</HTML>
실행결과 비교
다음과 같이 브라우저의 주소창에는 실행 파일명만 나타납니다.
http://localhost/object_asp/post_meth_view.asp
어떻습니까? 분명 틀리죠? 이제 GET과 POST의 차이가 어느 정도 명확해 진 것 같군요.
GET 방식은 정보를 URL의 끝에 질의 문자열로서 서버로 보내어지는 반면에
POST 방식은 HTTP 헤더에 숨겨져(인코드되어) 서버로 전송이 됩니다.
즉, GET 방식을 이용하면 아주 간단하게 정보가 가로채일 수 있는 거죠. 아주 쉽게....
또한 서버에서 정보를 추출하는 방법까지 서로 다르다는 걸 알 수가 있을 겁니다.