Dokumenty XHTML i ich typ MIME
Czym jest typ MIME?
- MIME
Multipurpose Internet Mail Extension czyli uniwersalny sposób opisu zawartości pakietu danych. Sposób ten został stworzony z zamysłem wykorzystania go przy przesyłaniu plików pocztą elektroniczną, ale okazał się na tyle dobry, że zaczęto stosować go szerzej.
Typy MIME składają się z dwóch części. Pierwszą z nich jest definicja głównego typu, po niej następuje slash, a po nim wyszczególnienie zawartości pliku. Podstawowe typy to:
- text
- image
- audio
- video
- application
- message
- multipart
Opisują one odpowiednio: pliki tekstowe, obrazy, dźwięki, pliki wideo, aplikacje oraz inne typy danych, części wiadomości pocztowych oraz dane, które złożone są z wielu różnych innych typów danych. Podtypów jest zbyt wiele, żeby je wypisywać. Przykładami pełnych typów MIME są: text/html - typ dla dokumentów HTML czy application/xml - typ dla rozbudowanych dokumentów XML. Te dwa typy będą, między innymi, nas interesowały w tym artykule.
XHTML i jego dziedzictwo
XHTML jest jedną z odmian XML-a, ale wzorowanym na HTML. Te zależności powodują sporo niejasności w kwestii przynależności XHTML-a i jego typu. Problem jest wcale nie taki błahy. Twórcy stron WWW, korzystający z nowych technologii nie zawsze zdają sobie sprawę z tego, że ich pewne niedopatrzenie może powodować wręcz lawinowy przyrost kolejnych kłopotów. A wszystko to przez tak zwany Quirks Mode, czyli tryb pracy przeglądarek, w którym jest zachowywana możliwie największa kompatybilność wsteczna z poprzednimi standardami. A czego innego spodziewać się po traktowaniu nowości "po staremu" jak nie kłopotów?
Organizacja World Wide Web Consortium, czuwająca nad standardami na stronach WWW, opublikowała dokument opisujący prawidłowość użycia odpowiednich typów dla poszczególnych języków używanych do tworzenia dokumentów hipertekstowych. Informacje te są dostępne pod adresem: http://www.w3.org/TR/xhtml-media-types/. Jednak mało kto zna ten dokument. A szkoda!
Przypisanie typu
Dokument hipertekstowy może mieć jeden z czterech typów:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
Przy czym pomiędzy dwoma ostatnimi typami, w praktyce nie występują duże różnice i, można powiedzieć, że są one równoważne.
Pierwszy typ - text/html służy oczywiście do opisu dokumentów napisanych w języku HTML 4.01 i starszych. Widać również, że dokument XHTML nie powinien przyjmować tego typu, gdyż jest XML-em wzorowanym tylko na HTML. Według tabeli podanej przez W3C dopuszczalne jest stosowanie typu text/html dla dokumentów XHTML 1.0 kompatybilnych z HTML, czyli w praktyce, dla dokumentów XHTML 1.0 Transistional oraz XHTML 1.0 Frameset. Należy jednak pamiętać, że jest to tylko dopuszczalne. Wskazane jest stosowanie typu application/xhtml+xml.
Tabela przypisania typów
Tabela ta reguluje kwestię odpowiednich typów dla poszczególnych typów dokumentów (pochodzi ze strony http://www.w3.org/TR/xhtml-media-types/#summary, na której znajduje się jej angielska, oficjalna, wersja).
| Typ MIME | HTML 4.01 | XHTML 1.0 kompatybilny z HTML (czyli, w praktyce, XHTML 1.0 Transistional oraz Frameset) | XHTML 1.0 Strict | XHTML 1.1 oraz XHTML Basic | XHTML wraz z MathML |
|---|---|---|---|---|---|
| text/html | powinien | dopuszczalne | nie powininen | ||
| application/xhtml+xml | niedopuszczalne | powinien | |||
| text/xml oraz application/xml | niedopuszczalne | dopuszczalne | |||
Problemy
Problemy niestety stanowią również przeglądarki. Wciąż najpopularniejszy na rynku Internet Explorer nie jest w stanie poradzić sobie z poprawnie serwowanymi dokumentami XHTML. Nie zna on typu application/xhtml+xml i przez to, stronę taką traktuje jako plik do ściągnięcia pytając się o miejsce jego zapisania. Problem pojawia się gdy mamy stronę, która jest wysyłana jako application/xhtml+xml a nie chcemy pozbawić użytkowników Internet Explorera możliwości jej obejrzenia. Jak to rozwiązać?
Poproś, a dostaniesz!
W protokole HTTP istnieją, między innymi, dwa nagłówki. Jeden z nich, nagłówek wysyłany przez serwer to Content-Type w którym jest przekazywana informacja na temat typu MIME treści właśnie wysyłanej do klienta (przeglądarki). Drugi z nich jest nagłówkiem klienckim (wysyłanym do serwera przez przeglądarkę). Nazywa się Accept i informuje serwer o typach danych, które jest w stanie przyjąć klient. A dzięki temu, że najpierw do głosu dochodzi przeglądarka można zastosować metodę "poproś, a dostaniesz".
Przykładowy nagłówek Accept wygląda następująco: Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5. Jak widać wymieniane są w nim poszczególne typy MIME, akceptowane przez przeglądarkę z ich priorytetem (wartość q). Na końcu jednak znajduje się typ ogólny - */*, czyli informacja dla serwera, że przeglądarka, jeśli serwer nie ma możliwości wysłania jednego z typów zadeklarowanych jawnie, przyjmie każdy typ. Dzięki temu właśnie można przy pomocy przeglądarki ściągać różnego rodzaju pliki. Jawna deklaracja typu zazwyczaj oznacza, że program bez większego problemu poradzi sobie z otwarciem dokumentu tego typu.
Przytoczony wcześniej nagłówek Accept to standardowy nagłówek wysyłany przez silnik Gecko, czyli silnik napędzający takie przeglądarki jak Mozilla czy Mozilla Firefox. Podobnie wygląda ten nagłówek w przypadku przeglądarki Opera. W przypadku Internet Explorera jest on skrajnie różny. W niektórych przypadkach Internet Explorer wysyła nagłówek: Accept: */* nie podając jawnie żadnego typu danych. Nigdy też nie znajduje się tam jawnie zadeklarowany typ application/xhtml+xml. I dzięki temu właśnie faktowi można rozwiązać problem poprawnego deklarowania typu dokumentu XHTML.
W metodzie "poproś, a dostaniesz" serwer sprawdza czy klient jawnie deklaruje typ application/xhtml+xml i, jeśli tak, wysyła mu dokument z takim typem. W innym przypadku dokument jest wysyłany jako text/html, co w niektórych przypadkach jest naruszeniem zaleceń W3C, ale jest też jedynym sensownym rozwiązaniem problemu.
Problem najlepiej jest rozwiązać przy pomocy PHP. Kod likwidujący problem ma zaledwie kilka linijek i nie stanowi problemu jego zaimplemetowanie na stronie.
<?php
if(strstr($_SERVER['HTTP_ACCEPT'], "application/xhtml+xml")) {
header("Content-Type: application/xhtml+xml");
}
else {
header("Content-Type: text/html");
}
?>
Kod ten ma pewną niedoskonałość. Może się zdarzyć, że typ application/xhtml+xml będzie mieć priorytet q równy zero. Skrypt mimo to będzie serwował przeglądarce typ, którego ona wyraźnie sobie nie życzy. Jednak nie spotkałem się jeszcze z przeglądarką, która stroniłaby od application/xhtml+xml w ten sposób. Na wszelki wypadek można jednak dodać sprawdzanie priorytetu i jego ewentualne porównywanie z priorytetem dla text/html.
Sprawdzenie, czy przeglądarka jawnie zadeklarowała typ application/xhtml+xml jest wykonywane przy pomocy zwykłego wyszukiwania ciągu znaków w innym ciągu znaków (w tym przypadku wyszukiwanym ciągiem jest "application/xhtml+xml", a ciągiem, w którym jest on wyszukiwany jest zawartość nagłówka Accept. Jeśli przeglądarka nie deklaruje tego typu jawnie (czyli nie informuje, że jest w stanie otworzyć taki typ dokumentu) wysyłany jest standardowy typ text/html, z którym radzą sobie wszystkie przeglądarki.
Po wysłaniu dokumentu XHTML z typem application/xhtml+xml należy pamiętać, że każdy błąd w kodzie strony może uniemożliwić jej poprawne odczytanie, ponieważ podczas parsowania dokumentu parser XML może wyświetlić błędy w kodzie zamiast samej strony. Jednak takie podejście uczy uważności i zachowywania czystości kodu, a co za tym idzie kształtuje umiejętność pisania dobrych, poprawnie złożonych stron WWW.
