Skip to main content

Bug Tracker

Side navigation

#13709 closed bug (notabug)

Opened April 02, 2013 09:02AM UTC

Closed April 04, 2013 09:57PM UTC

Last modified April 05, 2013 07:15AM UTC

.ajaxPrefilter() not working

Reported by: GolubevS79@gmail.com Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.9.1
Keywords: Cc: jaubourg
Blocked by: Blocking:
Description

This scenario is not working:

$.ajaxPrefilter("script json jsonp", function (options) {
    if (options.crossDomain) {
        options.crossDomain = false;
        options.url = "warning.htm";
        options.dataType = "html";

        return "html";
    }
});

$.ajax({
    url: "http://code.jquery.com/jquery-1.9.1.min.js",
    dataType: "script",
    success: function (data) {
        $("#target").append(data);
    },
    error: function (a, b, c) {
        $("#target").append(b);
    }
})

Result: "parseerror" (as result of parsing html by "eval" function), althought "dataType" equals "html" and other ajax settings in error callback is correct (but "dataTypes" equals ["text", "html", "script"])

Attachments (0)
Change History (5)

Changed April 04, 2013 07:30PM UTC by dmethvin comment:1

cc: → jaubourg

Another candidate for the jaubourg-shaped light. Seems like you'd need to modify .dataTypes[] (and it works if you do) but we don't document that.

http://jsfiddle.net/TbK6C/

Changed April 04, 2013 07:39PM UTC by jaubourg comment:2

dmethvin found the proper way to do what you want, though it could be simplified into:

options.dataTypes = [];
return "html";

The real question is why on earth you'd want to do something like this. How is the success handler supposed to know what kind of dataType it is receiving. Wouldn't it be simpler to abort the request in the prefilter with a proper reason?

if ( options.crossDomain ) {
    jqXHR.abort( "crossDomain" );
}

Changed April 04, 2013 09:26PM UTC by golubevs79@gmail.com comment:3

Success and error handlers in .ajax() has no importance here. The main reason is to prohibit cross domain requests and redirect user to some warning page (accordingly changing data type from script to html). The line

"options.dataType = "html"

in the .ajaxPrefilter() call ideally shouldn't be present (return "html" would be enough). It seems to me that the change of "dataTypes" array is some confusing (because it's your inner property) and change of documented "dataType" property would be sufficient.

In general, there is a main supervisor script that prohibits cross domain requests from other scripts with the help of following call:

$.ajaxPrefilter("script json jsonp", function (options) {
    if (options.crossDomain) {
        options.crossDomain = false;
        options.url = "warning.htm";

        return "html";
    }
});

It's would be very useful

Sorry for my english :)

Changed April 04, 2013 09:57PM UTC by jaubourg comment:4

resolution: → notabug
status: newclosed

It's the way you "redirect" I don't get.

You're deep into the ajax architecture, requesting some script or json, then you automagically transform the request into html. It doesn't make much sense.

When you return a string from a prefilter, you effectively add a dataType at the beginning of the list of dataType, you're not overriding the dataType entirely.

This is so you can transparently get advantage of the conversion logic using multiple dataTypes (see http://demo.creative-area.net/jqcon2011/#27 for an example).

By overriding the dataType like you wanna do in your prefilter you'll get stuff like this:

$.getScript( "http://path.to.other.domain/myScript.js", function( data ) {
    // Nothing was executed and data contains warning.htm
} );

How is this "redirecting"? What are you trying to achieve? If you wanna prohibit crossDomain request, just abort in the prefilter with a console warning to boot.

I'll close this as notabug because I'm convinced you need to think a little more about your use-case and the forums are better suited for this.

jQuery is working as expected here.

Changed April 05, 2013 07:15AM UTC by GolubevS79@gmail.com comment:5

Ok, let it be notabug :)

Of course do redirecting this way doesn't make sence. My use-case looks rather far-fetched because its sole purpose - to show that the value returned by the .ajaxPrefilter() does not override "dataType" property. Although it's documented as

''The $.ajaxPrefilter() method can also redirect a request to another dataType by returning that dataType. For example, the following sets a request as "script" if the URL has some specific properties defined in a custom isActuallyScript() function:''

$.ajaxPrefilter(function( options ) {
  if ( isActuallyScript( options.url ) ) {
    return "script";
  }
});

''This would ensure not only that the request is considered "script" but also that all the prefilters specifically attached to the script dataType would be applied to it.''

And now you say: ''When you return a string from a prefilter, you effectively add a dataType at the beginning of the list of dataType, you're not overriding the dataType entirely'' (i.e. "there is actually no data type redirection")

But everything is working properly if do as you mentioned above:

options.dataTypes = [];
return "html";

and though it looks some strange, thanks for that code.