2295 script tags later

What I did

So, building on my “Script: not a type-ical tag” article, I tested a few more ways to inject JavaScript into webpages. 1895 more, to be exact, :) (and I’m not done yet).

How I did it

Firstly, I changed the way I’m injecting scripts to use a PHP file like Mathias Bynens is in his tests (i.e. page.php?type=blah/blah&do=something). Here’s the end result for that PHP file:

<?php

$ct = preg_replace('/[^a-z\/\-]/', '', $_GET['ct']);
header('Content-Type: ' . $ct);

if (empty($ct)) {
    $ct = 'no type';
}

if (isset($_GET['dw'])) {
    echo "document.writeln('Content-Type: $ct works!<br>');";
}
else if (isset($_GET['id'])) {
    $id = preg_replace('/[^a-z_]/', '', $_GET['id']);
    echo <<<EOT
try {
    document.getElementById('{$id}').innerHTML
        = 'Content-Type: {$ct} works!';
}
catch (e) {
    alert("Couldn't find id of {$id}");
}
EOT;
}
else {
    die("// Nothing to do");
}

So this allows me to inject the scripts like so:

<script src="js.php?ct=application/javascript&todo"></script>

And they will set the HTTP Content-Type headers for external <script>s and do some stuff.

I also added data URIs, dynamic script creation and dynamic script injection (subtly different).

Data URIs scripts look like this:

<script src="data:X/Y,document.write('oh%20hai!')%3B"></script>

The dynamic script creation I'm doing looks like this:

window.onload = function () {
    var c = document.createElement('script');
    c.innerHTML = '// do something in JS!';
    document.body.appendChild(s);

And dynamic script injection looks like this:

    var i = document.createElement('script');
    i.src = 'js.php?do=something';
    document.body.appendChild(i);
};

Results

NOTE: I will be switching this to use Browserscope sooner or later, but for now the results of my very manual testing can be seen below.

Conclusions / Findings

So, some interesting things I found out from this were:

  1. Though IE8 supports data URIs in other areas (supposedly), it will not execute a <script> with a data URI as the src attribute (verified by Microsoft here). This has been changed in IE9. Go nuts.
  2. IE9 handles data URI encoding much more strictly than other browsers. Without properly encoding various parts of the inline data (i.e. / -> %2F, ; -> %3B) <scripts> will not execute nor give any particular reason why they didn't (as far as I could find). At first this lead me to believe that data URIs in <script> srcs weren't working in IE8 or IE9 at all!
  3. IE9 accepts many different type attributes on <script> tags like other "good" browsers. This is a large jump above IEs 6-8, :)
  4. A browser made by 90,000 geeks over 30 years is now being rivaled by the browser I have in my pocket on my phone (OK, that's not fair - Apple and Google both made Webkit & Chrome).

As always, let me know if you find problems with my results or if you want to contribute some results yourself.

This entry was posted in Compatibility, Cross-browser, JavaScript, Web. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>