티스토리 뷰
지난 글에 이어 생각해 볼만한 문제 회피 방법을 소개할까합니다. domain이 다른 상황에서 데이터를 요구하거나 전송하고자할 때 사용하는 방법으로 script tag 삽입(dynamic script tag)이라는 기법이 사용됩니다. (참고 1: 구글 책 검색) (참고2)
위 방법의 단점이 있으니 그것은, 위 방법은 GET 방식을 통해 이루어지는 URL 길이 제한에 걸린다는 것입니다.
검색 결과를 참고해봐서 인용하자면,
아쉽게도 IE의 경우 2083자 정도이고, 이것은 UTF8의 경우 URL에서 한글 인코딩은 한 글자당 9byte를 소비하므로, 호스트명이나 변수명등을 제외하면, 200자정도로 제한 되는 것을 알 수 있습니다.
따라서, POST를 쓸 수 밖에 없습니다만, 이 경우 script 태그를 통한 방법으로는 GET만 가능하므로 어렵습니다. 숨겨진 IFRAME을 만들고, 이 녀석 안에서 FORM을 만들어 전송하는 방법으로 해야겠습니다.
다음과 같은 방법을 소개합니다.
간단하죠? 단,iframe을 사용할 경우, iframe이므로 /api/addComment의 결과는 text/html과 같이 브라우져 안에서 해결할 수 있는 MIME 형식이어야합니다. 또한 callback이 동작하지 않습니다. FORM이 전송되고 나면, iframe은 더이상 www.example.com이 아닌 external.example.net 소속이 되므로, 부모에 접근할 수 없게 됩니다. 꼭, callback을 호출하고 싶을 때는 api의 결과창이 다시 redirect되어 상위에 접근할 수 있도록 바뀌어야합니다. 이것은 숙제로 남겨 둡....니다.
www.example.com: main.html
<script>위 스크립트는 도메인이 www.example.com에 있으면서, external.example.net이라는 외부 도메인의 글에 댓글을 달 수 있는 방법에 대한 하나의 예시입니다. 전형적이죠.
function draw( result )
{
if( result ) { alert("성공"); } else { alert("실패"); }
}
function addComment( id, comment )
{
var scr = document.createElement( "SCRIPT" );
scr.src = "http://external.example.net/api/get_tags?article_id="+
id+"&comment="+encodeURIcomponent(comment)+"&callback=draw";
document.body.appendChild( scr );
}
</script>
위 방법의 단점이 있으니 그것은, 위 방법은 GET 방식을 통해 이루어지는 URL 길이 제한에 걸린다는 것입니다.
검색 결과를 참고해봐서 인용하자면,
IE: 2083, FF: 65,536, Safari: 8,000, Opera: 190,000정도입니다.
Apache: ~4,000 IIS: 16,384
http://www.boutell.com/newfaq/misc/urllength.html
아쉽게도 IE의 경우 2083자 정도이고, 이것은 UTF8의 경우 URL에서 한글 인코딩은 한 글자당 9byte를 소비하므로, 호스트명이나 변수명등을 제외하면, 200자정도로 제한 되는 것을 알 수 있습니다.
따라서, POST를 쓸 수 밖에 없습니다만, 이 경우 script 태그를 통한 방법으로는 GET만 가능하므로 어렵습니다. 숨겨진 IFRAME을 만들고, 이 녀석 안에서 FORM을 만들어 전송하는 방법으로 해야겠습니다.
다음과 같은 방법을 소개합니다.
example.com: main.html
<script>
var request = {};
var requestCount = 0;
function addComment( id, comment )
{
request[requestCount] = {id:id, comment:comment};
var irf = document.createElement( "IFRAME" );
ifr.src = "post.html#"+ requestCount;
requestCount++;
document.body.appendChild( ifr );
}
</script>
example.com: post.html
<html>원리는 간단합니다. 숨겨 있는 IFRAME에서 자기의 주소 뒤에 오는 fragment (#) 부분을 해석하여, 부모 프레임에 숨겨 있는 개체에 접근합니다. 주소에 넣기 싫다면, 숨겨 있는 frame을 만들때 name에 넣어주고, window.name으로 접근해도 됩니다.
<head><meta http-equiv="Content-Type"
content="text/html; charset=utf-8" /></head>
<body>
<script>
var request = window.parent.request[document.location.hash.substr(1)];
var form = document.createElement( 'FORM' );
var key = document.createElement( 'INPUT' );
var value = document.createElement( 'INPUT' );
form.action =
"http://external.example.net/api/addComment?callback=dummy";
form.method = "post";
key.name = "article_id";
key.value = request.id;
value.name = "comment";
value.value = request.comment;
document.body.appendChild( form );
form.appendChild( person_id );
form.appendChild( key );
form.appendChild( value );
form.submit();
</script>
</body>
</html>
/* Dynamic script tag technique has limitation of URL max length */
간단하죠? 단,iframe을 사용할 경우, iframe이므로 /api/addComment의 결과는 text/html과 같이 브라우져 안에서 해결할 수 있는 MIME 형식이어야합니다. 또한 callback이 동작하지 않습니다. FORM이 전송되고 나면, iframe은 더이상 www.example.com이 아닌 external.example.net 소속이 되므로, 부모에 접근할 수 없게 됩니다. 꼭, callback을 호출하고 싶을 때는 api의 결과창이 다시 redirect되어 상위에 접근할 수 있도록 바뀌어야합니다. 이것은 숙제로 남겨 둡....니다.
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 대화
- 클레로덴드럼
- tattertools
- 퀴즈
- Linux
- 킹벤자민
- SSO
- 식물
- 디버깅
- Tattertools plugin
- SVN
- JavaScript
- BlogAPI
- 수선화
- 덴드롱
- TCP/IP
- macosx
- OpenID
- writely
- perl
- MySQL
- 벤자민
- nodejs
- ssh
- VIM
- 오픈소스
- 커피
- 구근
- Subversion
- url
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함