jquery 1.5 ajax的改进

轩辕阳焱
2023-12-01
源文见: http://api.jquery.com/extending-ajax/

相比之前的版本, 重写了ajax模块, 引入更多的扩展点. 三个概念:
[size=large]Prefilters[/size]
A prefilter is a callback function that is called before each request is sent, and prior to any $.ajax() option handling.
Prefilters are registered using $.ajaxPrefilter(), and a typical registration looks like this:

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
// Modify options, control originalOptions, store jqXHR, etc
});

[list]
[*]options are the request options
[*]originalOptions are the options as provided to the ajax method, unmodified and, thus, without defaults from ajaxSettings
[*]jqXHR is the jqXHR object of the request
[/list]

It is also possible to attach a prefilter to requests with a specific dataType. For example, the following applies the given prefilter to JSON and script requests only:

$.ajaxPrefilter( "json script", function( options, originalOptions, jqXHR ) {
// Modify options, control originalOptions, store jqXHR, etc
});


[size=x-large]Converters (注册自己的数据转换处理)[/size]
A converter is a callback function that is called when a response of a certain dataType is received while another dataType is expected.

Converters are stored into ajaxSettings and can be added globally as follows:

$.ajaxSetup({
converters: {
"text mydatatype": function( textValue ) {
if ( valid( textValue ) ) {
// Some parsing logic here
return mydatatypeValue;
} else {
// This will notify a parsererror for current request
throw exceptionObject;
}
}
}
});


Converters are useful to introduce custom dataTypes. They can also be used to transform data into desired formats. Note: all custom dataTypes must be lowercase.

With the example above, it is now possible to request data of type "mydatatype" as follows:

$.ajax( url, {
dataType: "mydatatype"
});


或者也可以直接写在ajax单独的一次处理里

$.ajax( url, {
dataType: "xml text mydatatype",
converters: {
"xml text": function( xmlValue ) {
// Extract relevant text from the xml document
return textValue;
}
}
});


[size=x-large]Transports (自定义整个的传输过程, 这是迫不得已才用)[/size]

A transport is an object that provides two methods, send and abort, that are used internally by $.ajax() to issue requests. A transport is the most advanced way to enhance $.ajax() and should be used only as a last resort when prefilters and converters are insufficient.

Since each request requires its own transport object instance, tranports cannot be registered directly. Therefore, you should provide a function that returns a transport instead.

Transports factories are registered using $.ajaxTransport(). A typical registration looks like this:

$.ajaxTransport( function( options, originalOptions, jqXHR ) {
if( /* transportCanHandleRequest */ ) {
return {
send: function( headers, completeCallback ) {
/* send code */
},
abort: function() {
/* abort code */
}
};
}
});


[list]
[*]options are the request options
[*]originalOptions are the options as provided to the ajax method, unmodified and, thus, without defaults from ajaxSettings
[*]jqXHR is the jqXHR object of the request
[*]headers is a map of request headers (key/value) that the transport can transmit if it supports it
[*]completeCallback is the callback used to notify ajax of the completion of the request
[/list]

completeCallback has the following signature:

function( status, statusText, responses, headers ) {}

[list]
[*]status is the HTTP status code of the response, like 200 for a typical success, or 404 for when the resource is not found.
[*]statusText is the statusText of the response.
[*]responses (Optional 可选) is a map of dataType/value that contains the response in all the formats the transport could provide (for instance, a native XMLHttpRequest object would set reponses to { xml: XMLData, text: textData } for a response that is an XML document)
[*]headers (Optional) is a string containing all the response headers if the transport has access to them (akin to what XMLHttpRequest.getAllResponseHeaders() would provide).
[/list]

Just like prefilters, a transport's factory function can be attached to specific dataType:


$.ajaxTransport( "script", function( options, originalOptions, jqXHR ) {
/* Will only be called for script requests */
});


The following example shows how a minimal image transport could be implemented:


$.ajaxTransport( "image", function( s ) {

if ( s.type === "GET" && s.async ) {

var image;

return {

send: function( _ , callback ) {

image = new Image();

function done( status ) {
if ( image ) {
var statusText = ( status == 200 ) ? "success" : "error",
tmp = image;
image = image.onreadystatechange = image.onerror = image.onload = null;
callback( status, statusText, { image: tmp } );
}
}

image.onreadystatechange = image.onload = function() {
done( 200 );
};
image.onerror = function() {
done( 404 );
};

image.src = s.url;
},

abort: function() {
if ( image ) {
image = image.onreadystatechange = image.onerror = image.onload = null;
}
}
};
}
});


[size=x-large]Handling Custom Data Types[/size]
在jquery源码里, 已定义了几种处理类型
The jQuery Ajax implementation comes with a set of standard dataTypes, such as text, json, xml, and html.

Use the converters option in $.ajaxSetup() to augment or modify the data type conversion strategies used by $.ajax().

The unminified jQuery source itself includes a list of default converters, which effectively illustrates how they can be used:


// List of data converters
// 1) key format is "source_type destination_type"
// (a single space in-between)
// 2) the catchall symbol "*" can be used for source_type
converters: {

// Convert anything to text
"* text": window.String,

// Text to html (true = no transformation)
"text html": true,

// Evaluate text as a json expression
"text json": jQuery.parseJSON,

// Parse text as xml
"text xml": jQuery.parseXML
}


When you specify a converters option globally in $.ajaxSetup() or per call in $.ajax(), the object will map onto the default converters, overwriting those you specify and leaving the others intact.

For example, the jQuery source uses $.ajaxSetup() to add a converter for "text script":

jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript"
},
contents: {
script: /javascript/
},
converters: {
"text script": jQuery.globalEval
}
});
 类似资料: