Komentarz to, czy może skrypt?

Michał ‘mina86’ Nazarewicz | 12 lutego 2008

Przenosząc się na Joggera straciłem sporo czasu na dochodzenie czemu skrypty, które zamieszczałem nie działały tak jak powinny (tzn. nie działały w ogóle). Okazało się, że zależnie od typu MIME strony skrypty są różnie interpretowane. A dokładniej mechanizmy ochrony skryptów.

Ze względu na przeglądarki nie rozumiejące tagu script przyjęło się kod skryptu umieszczać w komentarzu. Przeglądarki wspierające skrypty domyślały się, że to tak naprawdę kod skryptu i jakoś sobie z tym radziły. Ku memu lekkiemu zdziwieniu odkryłem, że Opera i Firefox przestają wykonywać kod skryptu, gdy strona jest dostarczona jako application/xhtml+xml. Aby sprawę zbadać bardziej szczegółowo stworzyłem taką oto stronę testową:

<?php
$type = isset($_GET['xml']) ? 'application/xhtml+xml' : 'text/html';
header('content-type: ' . $type . '; charset=iso-8859-2');
?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
          "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test</title>
  </head>
  <body>
    <p>Wysłany nagłówek Content-Type: <tt><?php echo($type); ?>;
        charser=iso-8859-2</tt>.</p>

    <script type="text/javascript"><!--
       alert('Skrypt "chroniony" komentarzem.');
    //--></script>
    <script type="text/javascript">alert('"Goły" skrypt.');</script>
    <script type="text/javascript"><![CDATA[
      alert('Skrypt "chroniony" przez CDATA.');
    ]]></script>
  </body>
</html>

Okazuje się, że wysyłając stronę jako text/html wykonują się dwa pierwsze, a jako application/xhtml+xml dwa ostatnie skrypty. Co to oznacza w praktyce? Otóż, mamy do wyboru:

  • wysyłanie typu text/html i wówczas naszemu dokumentowi XHTML będą towarzyszyły niepoprawne nagłówki,
  • wysłanie typu application/xhtml+xml i wówczas niektóre przeglądarki (np. IE) będą miały kłopoty z wyświetleniem strony,
  • zastosowanie negocjacji typu MIME i pozostawienie gołych skryptów powodując tym samym, że strona przestanie się walidować (chyba, że w kodzie skryptu nie będzie używany znak mniejszości, większości ani etka)(update: okazuje się, że coś mi się pomyliło z tym, że walidator W3C odrzuca takie dokumenty),
  • zastosowanie negocjacji i sprytnego mechanizmu po stronie serwera, który będzie stosował odpowiednie sekwencje otwierające i zamykające skrypt albo
  • zastosowanie negocjacji i trzymanie wszystkich skryptów w plikach, dołączanych do strony za pomocą elementu script z atrybutem src.

Cóż rzec… takie uroki XHTML-a.