admin管理员组

文章数量:1431406

Why isn't onload fired for script type="text/plain" ? loadPlain below doesn't fire the callback, but loadScript does.

I expected this to work... should it not?

    loadPlain("http://localhost/ajax/libs/jquery/1.10.2/jquery.min.js", function(element) {
            alert(1);
            alert(element.innerHTML);
    }, undefined, {})

    function loadPlain(path, callback, errorCallback, options) {
            var element = document.createElement('script');
            element.setAttribute("type", 'text/plain');
            element.setAttribute("src", path);

            return loadBase(element, callback, errorCallback, options);
    }

    function loadScript(path, callback, errorCallback, options) {
            var element = document.createElement('script');
            element.setAttribute("type", 'text/javascript');
            element.setAttribute("src", path);

            return loadBase(element, callback, errorCallback, options);
    }


    function loadBase(element, callback, errorCallback, options) {
            element.loaded = false;

            if (element.readyState){  // IE
                    element.onreadystatechange = function(){
                            if (element.readyState == "loaded" || element.readyState == "plete"){
                                    element.onreadystatechange = null;

                                    loadBaseOnload(element, callback);
                            }
                    };
            } else {                 // Others
                    element.onload = function() {
                            loadBaseOnload(element, callback);
                    };
            }

            element.onerror = function() {
                    errorCallback && errorCallback(element);
            };

            (options.elementAppendTo || document.head || loadBase.head || (loadBase.head = document.getElementsByTagName('head')[0]) || document.body).appendChild(element);

            return element;
    }

    function loadBaseOnload(element, callback) {
            if (element.loaded != true) {
                    element.loaded = true;
                    if ( callback ) callback(element);
            }
    }

Please note that I know about XMLHttpRequest, but thats not the question :)

Why isn't onload fired for script type="text/plain" ? loadPlain below doesn't fire the callback, but loadScript does.

I expected this to work... should it not?

    loadPlain("http://localhost/ajax/libs/jquery/1.10.2/jquery.min.js", function(element) {
            alert(1);
            alert(element.innerHTML);
    }, undefined, {})

    function loadPlain(path, callback, errorCallback, options) {
            var element = document.createElement('script');
            element.setAttribute("type", 'text/plain');
            element.setAttribute("src", path);

            return loadBase(element, callback, errorCallback, options);
    }

    function loadScript(path, callback, errorCallback, options) {
            var element = document.createElement('script');
            element.setAttribute("type", 'text/javascript');
            element.setAttribute("src", path);

            return loadBase(element, callback, errorCallback, options);
    }


    function loadBase(element, callback, errorCallback, options) {
            element.loaded = false;

            if (element.readyState){  // IE
                    element.onreadystatechange = function(){
                            if (element.readyState == "loaded" || element.readyState == "plete"){
                                    element.onreadystatechange = null;

                                    loadBaseOnload(element, callback);
                            }
                    };
            } else {                 // Others
                    element.onload = function() {
                            loadBaseOnload(element, callback);
                    };
            }

            element.onerror = function() {
                    errorCallback && errorCallback(element);
            };

            (options.elementAppendTo || document.head || loadBase.head || (loadBase.head = document.getElementsByTagName('head')[0]) || document.body).appendChild(element);

            return element;
    }

    function loadBaseOnload(element, callback) {
            if (element.loaded != true) {
                    element.loaded = true;
                    if ( callback ) callback(element);
            }
    }

Please note that I know about XMLHttpRequest, but thats not the question :)

Share Improve this question edited Aug 5, 2013 at 22:35 mjs asked Aug 5, 2013 at 13:47 mjsmjs 22.4k32 gold badges133 silver badges220 bronze badges 1
  • How are you using your function loadPlain? I ask because it seems similar in style to your function loadScript, so it may be in the way you're using it that is causing the issue. – Trendy Commented Aug 5, 2013 at 13:51
Add a ment  | 

2 Answers 2

Reset to default 8

The WHATWG (the organization who specifies browser behavior, alongside the W3C) has a list of known script MIME types and some blacklisted MIME types that must not be treated as scripting languages:

The following lists the MIME type strings that user agents must recognize, and the languages to which they refer:

  • "application/ecmascript"
  • "application/javascript"
  • "application/x-ecmascript"
  • ...

The following MIME types (with or without parameters) must not be interpreted as scripting languages:

  • "text/plain"
  • "text/xml"
  • "application/octet-stream"
  • "application/xml"

Note: These types are explicitly listed here because they are poorly-defined types that are nonetheless likely to be used as formats for data blocks, and it would be problematic if they were suddenly to be interpreted as script by a user agent.

What the WHATWG spec calls "data blocks" here are non-scripts enclosed in <script> tags:

In this example, two script elements are used. One embeds an external script, and the other includes some data.

<script src="game-engine.js"></script>
<script type="text/x-game-map">`
........U.........e
o............A....e
.....A.....AAA....e
.A..AAA...AAAAA...e
</script>

The ponents of the WHATWG spec that specify load events for <script> tags explicitly state that they fire for scripts referred to by <script> tags, not to non-script data blocks. A <script> element is a data block if its type is not recognized as a MIME type corresponding to a scripting language supported by the browser. This means that blacklisted types like text/plain will never be recognized as scripts, whereas type values in neither the must-support nor must-not-support list, like application/dart (for Google's Dart language) might be supported by some browsers.

Furthermore, including a non-script type alongside a src is not spec-pliant. Data blocks are legal only when specified inline:

When used to include data blocks (as opposed to scripts), the data must be embedded inline, the format of the data must be given using the type attribute, the src attribute must not be specified, and the contents of the script element must conform to the requirements defined for the format used.

If you specify your script as "text/plain" the browser wont do anything with it.

You must specify it as "script/javascript" to have it execute as JavaScript.

本文标签: