.htaccess의 예

php_flag register_globals on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^(www)\.domain\.co\.kr$ [NC]
RewriteRule (.*) http://www.domain.co.kr/$1 [R=301,L]
ErrorDocument 401 http://www.domain.co.kr/401error.html


간단하게 요정도?
난 RewriteCond와 RewriteRule에 대해서만 언급해보려한다.
RewriteEngine On은 Rewrite모듈의 사용을 위해 기본적으로 On으로 설정해두는것이 좋다.
RewriteBase는 기본적으로 .htaccess가 위치안 물리적 경로로 설정하지만 Rewrite의 쓰임이 너무 광범위하기에 다르게 쓰이는 경우도 많다.
그 외에 RewriteOptions, RewriteLog, RewriteLogLevel, RewriteLock, RewriteMap등은 심화과정이므로 취급하지 않습니다 ^^;;

이 글은 완벽하지 않다. 잘쓴 글도 아니고 잘 되어있는 글도 아니다.
하지만 당신이 컴퓨터에 대한 열정이 있고 그만큼의 노력이 있었으며 독학에 재능이 있다면 이정도의 글로도 만족할것이라 믿는다. (쓸데없는 잡담이 너무 많은거 뺴고... ㅡㅡ;;)

이제 본론으로 고고-


Rewrite모듈은 URL Rewrite 엔진일까?

RewriteCond와 RewriteRule의 기본 형태
RewriteCond와 RewriteRule의 기본 형태는 이렇다.
RewriteCond     TestString     CondPattern
RewriteRule     Pattern     Substitution

RewriteCond는 RewriteRule을 위해 존재하기도 하지만 RewriteRule은 RewriteCond를 위해 존재하기도 한다.
하지만 순서는 거의 대부분 Cond후에 Rule이 온다.
Cond는 생략하고 Rule만 있는경우도 많다.
기본형태는 이러하지만 RewriteCond만 있을수도 있고 RewriteRule만 있을수도 있으며 둘다 여러개일수도 있고 둘중 하나만 여러개일수도 있다. 순서도 맘대로라서 엄청나게 다양한 수법이 가능하다 ㅋ

처리 경로(흐름)
제일 먼저 Rule의 Pattern에 어긋나지 않는다면 Cond의 TestString으로 가서 조건검사를 시작한다. 그후 CondPattern을 지나 Substitution으로 처리되어 조건에 만족하게 된다.

다음을 보자

...
RewriteRule     Pattern     Substitution

RewriteCond     TestString     CondPattern
RewriteRule     Pattern     Substitution

RewriteRule     Pattern     Substitution
...

위의 경우 Cond와 Rule이 막 써있다 ㅋ 두개 이상의 Rule이 있을경우 위  Rule이 처리, 적용된 결과가 다시 두번째 Rule에 적용된다. 또 아래 Rule이 있다면 그 결과가 다시 검사될것이다.
혹은. 위의 조건에 맞지 않는 값이라면 다음 Rule로 넘긴다.


이하부터는 패턴, 대용(대체), 조건패턴등의 한글화를 섞어 쓰겠다.
Cond는 조건의 약자이고 Rule은 그대로 규칙, 법이다.

특수 문자
프 로그래밍을 하면서 그 프로그램 내부 코드나 명령어로 쓰이고 있어서 쓰지 못하는 문자가 많다. 여기서도 마찬가지이다. 하지만 어디서나 존재하는 Escape문자 있으니 여기서는 "\"(역슬래쉬(원))표시가 쓰인다. 보통 .이 잘못쓰일것을 대비하여 \.로 쓰는게 보통이다.
예 : domain.co.kr   ==>   domain\.co\.kr
주로 점.이나 대괄호[], 괄호()등에 쓰인다.

RewriteCond
RewriteCond의 기본 구문은 이미 위에서도 나왔다.
그곳 Test스트링부분에 $N이나 %N이 쓰인다면 역참조 기능을 제공하게된다.
여기서 N은 (1<=N<=9)이다.
$N의 경우 현재 처리되고있는 Rule에서 가르키고 있는 패턴이 그룹으로 묶여 제공된다.
$N을 하나의 변수처럼 사용할수 있게되는것이다.
아래도 나와있지만 괄호로 그룹을 묶은 부분이 변수로 사용된다.

RewriteCond   %{HTTP_HOST}             ^[^.]+\.domain\.co\.kr$
RewriteRule   ^(.+)                     %{HTTP_HOST}$1 [C]
RewriteRule   ^([^.]+)\.domain\.co\.kr(.*)   /home/$1/htdocs$2

위 예제의 경우 도메인 앞의 URI를 $1로 그 뒤 경로를 $2로 지정하여 특정 디렉토리의 내용을 읽도록 하는 내용이다.
이것을 짧게 한줄로 고쳐보자면

RewriteRule ^([^.]+)\.domain\.co\.kr(.*) /home/$1/htdocs$2

요정도?

%N은 현재 처리중인 Cond에서 가르키고있는 조건과 일치한 패턴이 그룹으로 묶여 제공된다.
이건 잘 안쓰이는것같아서 정말 잘쓰이는 다음으로 패쓰~

%{Name}의 경우 해당 서버의 변수를 가지고 올수있다.
변수의 개수는 정말 엄청나게 많다. 하지만 자주 쓰이는 변수들은 아래를 통해서 한번 확인해보세요 ^^

Server Name : domain.com
Protocol : HTTP/1.1
Server Port : 80
Method : GET
Servlet Path : /index.php
Remote Host : 192.168.0.4
Remote Port : -1
Remote Address : 192.168.0.4
Content Length : 0
Header_Accept : text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Header_User-Agent : Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
Header_Referer : null
Local Name : domain.com
Local Port : 80
Locale : ko_KR
Scheme : http
Request URI : /index.php

Request URL : http://domain.com/index.php


CondPattern
CondPattern에서 쓰이는 내부 명령어? 특수명령어?등을 알아보도록하자

-d     =>     디렉토리를 뜻한다.
결론적으로 Test스트링이 디렉토리를 가리키거나 포함하고 있을때 처리된다.
-f     =>     파일을 뜻한다.
Test스트링이 파일을 가리키거나 포함하고 있을때 처리된다.
-l     =>     심볼릭링크를 뜻한다.
Test스트링이 심볼릭링크를 가리키거나 포함하고 있을때 처리된다.
심볼릭 링크가 뭐냐고 물으신다면 리눅스나 유닉스를 공부해보세요 ^^ 라고 답하고 싶다^^

그리고 느낌표(!)는 부정을 뜻한다.

 

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://test.domain.co.kr/$1

위의 예제는 Request내용이 디렉토리나 파일을 가르키고 있지 않을경우 저쪽 사이트로 돌리라는 뜻. ^^
$1로 하위주소는 유지하려하고 있습니다 ^^

[Flag]
라인마다 Flag라 불리우는 깃발을 달수가 있습니다. 일종의 옵션으로 작용합니다 ^^

F     =>     403에러 Forbidden페이지로 된다.
L     =>     Last라는 뜻입니다. 위의 Cond들은 여기까지만 적용된다
아래부터는 새로 시작 되겠지용~
N     =>     새로운 Rule이 시작된다는 깃발.
QSA     =>     Cond의 대용을 지난 결과에 덧붙인다.
NE     =>     Out될 값에 특수문자가 HexCode로 되어 포함되어있는경우
R     =>     리다이렉션. 무조건 넘긴다. 뒤 주소로 넘긴다는 뜻이지요 ^^
NC     =>     대소문자 구별없다는 뜻.
OR     =>     프로그래밍의 or와 비슷하다.


아래를 참고하시죠 ^^

RewriteCond %{REMOTE_HOST}  ^domain.*  [OR]
RewriteCond %{REMOTE_HOST}  ^DOMAIN.*  [OR]
RewriteCond %{REMOTE_HOST}  ^DOMAIN2.* [NC]
RewriteRule ^(.*)$ http://www.domain.co.kr/$1 [R,L]

domain나 DOMAIN나 DOMAIN2나 domain2로부터 접속한 접속에 대하여 리다이렉트한다. http://www.domain.co.kr/로 접속하게된다. 보통 IP주소를 적게되겠다.

RewriteRule
여기부터는 아주 간단간단하게... ㅡㅡ;

텍스트

.     =>     ?과 같습니다. 무엇이든 하나의 문자를 뜻합니다. A가 될수도 있고 Z가 될수 있다. 반드시 한글자.
[A]     =>     역시 하나의 문자가 올수 있다는 뜻. ex) a[eo]t => aot 혹은 aet
[^A]     =>     문자는 올수 없다는 뜻~ A부터 Z까지~



 

?     =>     0개 또는 1개의 텍스트.
*     =>     0개 또는 1개 이상의 텍스트.
+     =>     1개 이상의 텍스트. 0은 될수 없다.



그룹

(텍스트)     =>     위의 텍스트에 속한 세가지를 조합하여 쓸수 있다
예로 (..)는 두글자라는 거지요 ^^
몇번째 그룹이냐에 따라서 위에 설명한 $N의 변수로 불러 쓸수있니다.



Anchors

^     =>     줄의 시작을 나타낸다 ex) ^a => a로 시작
$     =>     줄의 끝을 말한다. ㄷㅌ) a$ => a로 끝



[ PHP ] 정규식

Web Dev/PHP 2011. 6. 1. 11:09 Posted by ditus
출처 : http://cheolgoon.tistory.com/69


우선 간단한 정규식 표현
-------------
[abc]     a,b,c 로 이루어진 문자열
[a-c]     a 에서 c 까지의 문자로 이루어진 문자열
[a-z]     a 에서 z 까지의 문자로 이루어진 문자열
[A-Z]     대문자 A 에서 Z 까지의 문자로 이루어진 문자열
[a-zA-Z]  소문자 a 에서 z 까지, 대문자 A 에서 Z 까지의 문자로 이루어진 문자열
[0-9]     0 에서 9 까지의 숫자(문자?) 로 이루어진 문자열
[!@#_0-9] !,@,#,_ 와 0 에서 9 까지의 문자로만 이루어진 문자열
-------------

바로 앞 문자열의 개수를 지정하는 중괄호 {}
중괄호는({}) 는 바로 앞의 문자나 문자열의 개수를 지정해 주는 특수문자로, 사용 형식은 다음과 같다.

--------------
사용예제  내용
a{2}b     aab 를 가진 문자열을 사용할 수 있다. 즉 (2) 는 {} 앞에 있는 문자 a 의 개수가 2개인 것을 의미
a{2,}b    a 의 개수가 최소 2개 이상인 문자열을 의미. aab, aaab, aaaab 모두 사용할 수 있다.
--------------

시작과 끝을 알리는 ^,$
^,$ 는 문자열의 시작과 끝을 알리는 특수문자이다.
만약 abc 라는 문자열이 있으면 이 문자열은 a 로 시작하여 c 로 끝난다.
이때 정규 표현식에서 a 부터 검사하라는 의미로 a 앞에 문자열의 시작을 알리는 ^ 를,
c 의 끝에 문자열의 끝을 알리는 $ 를 붙여서 정규 표현식을 시작한다.
^,$ 를 표로 정리하면 다음과 같다.
---------------
사용예제  내용
^abc      a 에서부터 문자가 시작되는 것을 알린다.
abc$      c 가 문자열의 끝임을 알린다.
---------------

문자열 사용 막기:
사용할 수 있는 문자열을 지정하는 정규 표현식의 문자는 [] 이다.
이와 반대로 특정 문자열을 사용할 수 없도록 지정하고 싶다면, 지정하는 대괄호 [] 사이에 삿갓(^) 표시를 입력하면 된다.
예를 들어 [^123] 과 같이 사용하면 1,2,3 숫자는 문자열로 사용할 수 없다.

<?
$text = "test1234";
$result = ereg("^[a-z]{4}[0-9]{4}$",$text);
echo $result."<br>"; // 1 출력
/*
[a-z]{4} 의 의미는, 위의 문자가 알파벳 a 에서 z 까지 4개의 문자로 이루어진 것인지 검사하는 양식이다.
test 는 소문자 a 에서 z 까지 4개의 알파벳 문자로 이루어진 것이고, 1234 는 0 에서 9 까지의 숫자중에서 4개로 이루어진 값이므로,
True 인 1 을 반환한다.
*/
?>

바로 앞 문자열의 반복을 의미하는 *,+,? 문자
*,+,? 문자들은 해당 문자의 바로 앞 문자를 의미하며, 그 문자가 하나 이상이라는 것을 의미한다.
이 세 개의 문자열은 비슷한 정의를 가지고 있지만, 실제 사용하는 데에는 약간의 차이를 갖는다.
다음은 이 세 가지 특수문자열을 정의하고 실제 사용하는 예를 나타낸 표이다.

--------------------------------------
사용예제 결과값                  내용
a*b      b,ab,aab,aaab,aaaab...  b 앞에 a 가 없거나 하나 이상 존재하는 모든 문자열
a+b      ab,aab,aaab,aaaab...    b 앞에 a 가 최소한 하나 이상은 존재하는 모든 문자열
ab?c     abc, ac                 a 와 c 사이에 b 가 하나 있거나 혹은 없는 문자열
--------------------------------------

정규 표현식에서 특수문자를 사용하기 위한 역슬래시(\)
정규 표현식에서 입력받은 문자열의 타당성을 검사하기 위한 특수문자가 아니라,
실제 사용해야 할 특수문자가 있을 때는 그 문자 앞에 역슬래시(\)로 해당 문자열을 이스케이프해야 한다.
특수문자를 이스케이프 한다는 이유는, 우리가 이메일이나 홈페이지 주소 등을 정규 표현식으로 검사할 때
실제 'small@small.co.kr' 와 같이 이메일 주소에 사용하는 특수문자 '.' 는 그대로 살려야 하기 때문이다.

정규 표현식 특수문자를 이용하여 이메일 주소 체크하기

$ereg = "^[_0-9a-zA-Z]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)+$";

예시 이메일주소)
small@small.co.kr

맨앞의 사용자 계정은 영문 소문자와 대문자, 숫자 그리고 음수 기호(-), 언더바(_), 점(.)과 같은
특수문자의 조합으로 구성되므로, 다음과 같은 정규 표현식을 작성할 수 있다.

^[_0-9a-zA-Z-]

정규 표현식에서 ^ 문자는 문자열의 시작을 알리는 것이다.
처음 문자열인 사용자 계정 이름의 시작을 0 에서 9 까지의 숫자나 소문자 a 에서 소문자 z, 대문자 A 에서 대문자 Z 까지 사용하게 지정.
그런데, 사용자 계정에서
.small@small.co.kr 이나 small.@small.co.kr 처럼 사용자 계정의 이름을 점(.) 으로 시작하거나 끝낼수는 없으므로,
아래의 하나의 패턴을 더 추가한다.

^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*

여기서 마지막 문자열 * 는 바로 앞에 있는 괄호의 반복 () 을 뜻한다.
따라서, small, small.co, small.co.kr 등의 값들이 모두 참이 된다.
하지만, 실제 이런 사용자 계정은 없으므로,
입력한 사용자 계정 이름을 가져오고 이메일 계정을 의미하는 @ 를 붙여준다.

다시 이메일 주소의 서버 이름의 체크 정규 표현식을 만든다.
사용자 계정 이름을 검사하는 정규 표현식과 서버 이름 체크의 정규 표현식이 거의 비슷하므로,
다음과 같이 앞부분을 복사하여 하나 더 만들고, 서버 이름에는 언더바(_) 가 업으므로, 언더바(_) 를 지운다.
또, 서버 이름을 체크하는 정규 표현식이 끝나면 더 이상 이메일 주소가 없기 때문에 맨 마지막에 문자열의 끝을 알려주는 $ 문자를 입력한다.

^[_0-9a-zA-Z-]+(\.0-9a-zA-Z-]+*@(0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)+@

이제 정규 표현식과 eregi 함수만으로 이메일 주소의 타당성을 검사할수 있다.

표현식에서 () 는 그 부분들을 묶어주는 역할을 하는 듯 하다(일반 연산에서와 같은 방식으로)
단, ()* 로 사용하면,() 안의 내용을 반복 한다는 뜻.


<?
$ereg = "^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)+$";

$email = ".asdf.ae@asdf.co.kr";

$result = eregi($ereg,$email);
if($result==1){
  echo "입력하신 이메일 주소 $email 는 정상적인 이메일 주소입니다";
}else{
  echo "$email 는 정규 표현식에 어긋나는 이메일 주소 입니다";
}
?>

정규식에 일치하면 1 을 반환. 아니면 반환값 없음.

위의 이메일 주소가 정상적이라고 출력됨(정규 표현식 불완전)


현재 웹어플리케이션을 개발하기 위해 한창 프로젝트를 진행하고 있거나, 기존 웹사이트를 유지보수 하고 있는 개발자들에게 Internet Explorer 8(이하 IE8)의 등장은 부담이 아닐 수 없다.

현재 수행중인 프로젝트의 경우에도 초기에 웹 표준 준수를 목표 잡고 Internet Explorer, Firefox 등 다양한 브라우저와 버전들에서 테스트를 병행하여 개발을 진행해왔다. 그럼에도 불구하고 새롭게 등장한 IE8 버전에서 테스트한 결과, 페이지 레이아웃이 다소 깨지거나 동작에 문제가 발생하는 부분들이 발생하였다. 프로젝트 시작하던 올 초 IE8 출시를 예고되던 시점부터 우려하던 내용이 현실이 되고말았다.

지난주 IE8에서 사이트의 레이아웃이 깨지는 것이 크게 이슈화되었고, 이를 처리하기 위한 방법을 고민하던 중 다행히 간단한 코드를 통하여 전체 페이지의 레이아웃을 바로잡을 수 있었다.

다음은 meta.jspf 의 일부인데, 내가 한 작업이라고는 첫번째 메타(META) 태그를 추가한 것이 전부이다.

 
<%@ page pageEncoding="utf-8" %> 
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/> 
<meta http-equiv="Cache-Control" content="no-store"/> 
<meta http-equiv="Pragma" content="no-cache"/> 
<meta http-equiv="Expires" content="0"/> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 


아래 IE8에서 테스트한 화면을 보면 Poll 설문조사 부분이 완전히 어긋나 있다.

사용자 삽입 이미지

meta 태그를 적용후 다음과 같이 바로잡혔다.

사용자 삽입 이미지

한가지 더 예를 들면, 다음과 같이 테이블 형태가 깨지던 화면이

사용자 삽입 이미지

정상의 모습으로 돌아왔다.

사용자 삽입 이미지

간단하게 meta 태그를 추가함으로써 대부분의 문제는 바로잡혔지만, 전체 문제가 해결된 것은 아니다. 바로 윗 그림을 보면 검색 버튼의 우측에 우리가 의도하지 않았던 파이프 형태의 라인이 들어간 것이 보인다. 소소한 부분들에 대해서는 확인하고 처리할 수 밖에 없을 것 같다.

개발하는 입장에선 부담이 되지만 IE8은 기존의 IE6, IE7에 비해 월등히 향상된 렌더링 성능을 보여주고 있다고 한다. 실제로 웹서핑을 해보면 체감할 수 있을 수준이다. 그리고 한가지, IE8은 자체에 괜찮은 개발자 툴을 제공하고 있다.

사용자 삽입 이미지

웹표준 적용을 위해 기존 웹사이트에 대한 IE8 브라우저에 대한 호환성을 제공하기 위한 방안 중, 가장 권장되는 수준은 웹어플리케이션을 웹 표준에 맞도록 다시 검증하고 HTML과 CSS, Javascript 등을 수정하는 방법이다. 여건에 따라 이것이 용이하지 않다면 위의 예와 같이 <META> 태그를 이용하는 방안을 권장한다. 단, 전체 페이지가 잘 설계되고 구조화되어 있어야 적용이 쉽다는 것과 <META> 태그가 모든 것을 해결해주지는 않는다는 점을 염두에 두어야 한다.

메타(META) 태그를 적용하는 방법은 두가지이다.

  - 페이지 헤더에 메타 태그(X-UA-Compatible)를 추가한다. 이 메타 태그는 여타 태그들 보다 상단에 기술되어야 한다.
  - 서비스단의 자바 코드를 사용해 응답 헤더에 덧씌운다.

메타 태그 외에도 몇가지 방법들이 있는데, 내 위키에 간략히 정리한 것을 다시 붙여본다(내용은 마소의 지난 기사 중 "Internet Explorer 8 스페셜 리포트"에서 참고, 인용했음을 밝힌다).

DTD가 없는 웹 사이트 대응 방법

  • Quirks Mode란 DTD를 표준에 따라 인식하지 못했던 과거의 IE5 브라우저의 렌더링을 그대로 흉내 내는 모드다.

DTD가 있는 웹 사이트 대응 방법

DTD가 있고 IE5에 최적화 된 페이지 대응 방법

DTD가 있고 IE5에 최적화된 웹 페이지는 HTML 소스 코드 <head>…</head> 안쪽에 다음과 같은 코드 한 줄을 포함시키면 된다.

<meta http-equiv="X-UA-Compatible" content="IE=5"/>

IE8은 이 명령을“나는 IE5에 최적화된 페이지 입니다. Quirks Mode로 렌더링 해 주십시오”로 받아들여진다.

DTD가 있고 IE6에 최적화 된 페이지 대응 방법

IE6에 최적화 된 페이지는 IE7에 최적화 작업 후 다음 코드로 대응한다.

<meta http-equiv="X-UA-Compatible" content="IE=7"/>

IE8은 이 명령을“나는 IE7에 최적화된 페이지 입니다. IE7 표준 모드로 렌더링 해 주십시오”라고 받아들인다.

DTD가 혼재되어 있는 웹 사이트 대응법

DTD가 없는 페이지는 IE8이 Quirks Mode로 렌더링 하기 때문에 아무런 대응을 하지 않아도 페이지는 깨지지 않는다. DTD가 있는 페이지에 한하여 IE7에 최적화 시킨 후 다음 코드를 적용 하면 된다.

<meta http-equiv="X-UA-Compatible" content="IE=7"/>

만약 이런 호환 유도 코드를 DTD가 있는 페이지에만 별도로 적용하는 것이 어렵다면 모든 페이지에 호환 유도 코드를 추가하는 방법도 있다. DTD가 있는 페이지만 IE7에 최적화 시킨 후 모든 페이지에 다음 코드를 적용한다.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>

DTD가 없는 페이지는 여전히 Quirks Mode로, DTD가 있는 페이지는 IE7 표준 모드로 렌더링 할 것이다. 따라서 DTD가 있는지 없는지 여부에 관계없이 무조건 IE7 표준 모드로 렌더링 하는‘IE=7’보다 DTD가 있고 없음에 따라 자동으로 렌더링 모드를 전환해 주는‘IE=EmulateIE7’코드를 더욱 권장 한다.

호환 유도 코드를 서버측 응답 헤더에 적용하는 방법

모든 페이지에 일일이 호환 유도 코드를 추가하는 것은 아무리 봐도 효율적이라고 생각할 수 없다. 따라서 서버 사이드 개발자는 서버측 응답 헤더에 다음과 같이 적용할 수 있다. 이 코드는 웹 사이트에 전체적으로 호환 유도 코드를 삽입하는 것과 같은 효과를 거둘 수 있다.

* IIS에 적용할 코드

 
<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
  <system.webServer> 
    <httpProtocol> 
      <customHeaders> 
        <clear /> 
        <add name="X-UA-Compatible" value="IE=EmulateIE7"/> 
      </customHeaders> 
    </httpProtocol> 
  </system.webServer> 
</configuration> 


* Apache에 적용할 코드

X-UA-Compatible:IE=EmulateIE7

IE8은 DTD가 없거나 표준 DTD가 아닌 페이지를 만났을 때 Quirks Mode로 렌더링 하고, 표준 DTD를 만났을 때 IE7 표준 모드로 렌더링 할 것이다.

웹 표준 사이트와 낡은 브라우저의 호환성 문제

웹 표준 사이트는 IE8에 별도로 대응할 필요가 없다. IE8이 웹 표준을 잘 지원하고 있기 때문이다. 그러나 웹 표준을 잘 지킨 사이트는 낡은 브라우저에서 깨질 것이다. 낡은 브라우저는 웹 표준을 완전히 지원하지 않기 때문이다. 또한, 낡은 브라우저라고 해서 다 같은 브라우저가 아니다. IE7, IE6, IE5 세 가지 버전의 브라우저 엔진은 지원하는 표준의 범위가 다르기 때문에 렌더링도 각각 다르다. 렌더링 엔진이 제각기 다르기 때문에 각각의 버전에 대응하는 CSS 코드도 달라야 한다. CSS 코드를 적용함에 있어 버전 타깃팅 기법이 필요하다. 다행히도 IE는 조건부 주석이라는 또 다른 호환 유도 코드를 제공하고 있다.

 
<link rel="stylesheet" type="text/css" href="default.css"/> 
<!?[if IE7]> 
  <link rel="stylesheet" type="text/css" href="ie7.css"/> 
<[endif]?> 
<!?[if IE6]> 
  <link rel="stylesheet" type="text/css" href="ie6.css"/> 
<[endif]?> 
<!?[if IE5]> 
  <link rel="stylesheet" type="text/css" href="ie5.css"/> 
<[endif]?> 


ie7.css 파일은 IE7 버전에만 작용한다. ie6.css 파일은 IE6 버전에만 작용한다. ie5.css 파일은 IE5 버전에만 작용한다. 나머지 브라우저들은 default.css 파일만 파싱하며 ie7.css, ie6.css, ie5.css 파일에 대한 링크를 주석으로 처리한다.

CSS Hack 활용하기

권장하지는 않지만 CSS Hack을 사용하는 방법도 있다. CSS Hack은 브라우저의 버그를 이용하여 문제를 해결하는 방법이다. 버전별로 CSS 파일을 각각 작성하지 않아도 간편하게 낡은 브라우저에 대응할 수 있지만 CSS 문법 규격에 맞지 않는 것이 흠이다. 앞쪽에 선언된 property:value 값은 표준 계열 브라우저(IE8, 파이어폭스, 오페라, 사파리, 크롬)에서 작용하고 뒤에 선언된 property:value 값은 IE 버전에 대응하며 앞에 선언된 속성과 값을 덮어 쓴다.

IE5 ~ IE7 대응‘*’Hack

 
#selector { property:value; *property:value; } 
/* 문서의 DTD와 무관하게 작용함 */ 

IE5 ~ IE6 대응‘_’Hack

 
#selector { property:value; _property:value; } 
/* DTD가 없는 문서는 IE7에도 작용함 */ 

IE5 대응‘_ & /**/ ’Hack

 
#selector { property:value; _property /**/:value; } 
/* DTD가 표준모드인 경우에만 작용함 */ 

IE5 대응 Hack의 경우 /**/ 주석 앞에 한 칸의 공백이 있음에 유의한다.


참고로 아직도 여전히,

한국의 IE 버전별 점유율(2009년 2월 Internet Trend 보고서 기준)에 따르면 10년 전에 출시된 IE6 브라우저의 점유율이 59.42%로 가장 높고 IE7이 38.81% 대의 점유율을 보이고 있다. 또한 기타 브라우저들의 점유율도 큰 차이를 보인다. 파이어폭스와 사파리, 오페라, 크롬 브라우저의 지구촌 점유율이 통틀어 32.58%나 되는데 비하여 한국에서는 고작 1.4%에 그치고 있다.

고 한다. 파폭을 쓰는 사람은 개발자들이 다인 것 같다.


출처 : http://kyungseo.pe.kr/blog