Komentarz to, czy może skrypt?

Posted by Michał ‘mina86’ Nazarewicz on 12th of February 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.