Bug Tracker

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#13709 closed bug (notabug)

.ajaxPrefilter() not working

Reported by: GolubevS79@… 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"])

Change History (5)

comment:1 Changed 6 years ago by dmethvin

Cc: jaubourg added

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/

comment:2 Changed 6 years ago by jaubourg

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" );
}

comment:3 Changed 6 years ago by golubevs79@…

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 :)

comment:4 Changed 6 years ago by jaubourg

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.

comment:5 Changed 6 years ago by GolubevS79@…

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.

Note: See TracTickets for help on using tickets.