Introduction

When jQuery's .ajax() function recieves data with a script mimetype its default behavior is to execute the script. This is not always desirable and there is no obviously documented way to disable this. However, examination of the jQuery source code reveals how this can be done.

The Issue

When using the jQuery.ajax() function it inspects the mimetype of the resource returned by the server and, if it is a valid JavaScript mimetype, it executes the script. We may not want this behavior and, if we don't, disabling it isn't covered in the documentation.

An example of an Ajax request that triggers this behavior is:

 $.ajax({
   url: 'http://domain/js/javascript.js', // Returns a `text/javascript` mimetype.
   success: function (js_code) {
     console.log(js_code);
   }
 });

Whilst the JavaScript code will be logged to the console as expected it will also be executed due to some magic within jQuery.

Inspection of the code for the issue

Inspection of the jQuery source code for the script handling of Ajax requests reveals that when a JavaScript mimetype is detected it adds a convertor that executes the contents of the request before returning it:

converters: {
  "text script": function( text ) {
    jQuery.globalEval( text );
    return text;
  }
}

The Solution

Having identified the issue we can simply override the text script converter with a function that returns the code without executing it:

 $.ajax({
   url: 'http://domain/js/javascript.js',
   converters: {
     'text script': function (text) {
       return text;
     }
   },
   success: function (js_code) {
     console.log(js_code);
   }
 });

It is possible to set this converter as the default by using jQuery.ajaxSetup but, as the documentation states:

Note: The settings specified here will affect all calls to $.ajax or AJAX-based derivatives such as $.get() . This can cause undesirable behavior since other callers (for example, plugins) may be expecting the normal default settings. For that reason we strongly recommend against using this API. Instead, set the options explicitly in the call or define a simple plugin to do so.

References & Resources

  • N/A