Wikipedia:WikiProject User scripts/Guide/Ajax: Difference between revisions
jQuery |
Updated with jQuery examples. See also mw:RL/JD#ajax.js and mw:RL/DM#jQuery & plugins |
||
Line 1: | Line 1: | ||
{{update|type=Wikipedia help page}} |
|||
[[Ajax (programming)|AJAX]] (''asynchronous JavaScript and XML'') is a popular name for a web programming technique that queries the server or fetches content without reloading the entire page. |
[[Ajax (programming)|AJAX]] (''asynchronous JavaScript and XML'') is a popular name for a web programming technique that queries the server or fetches content without reloading the entire page. |
||
While programming AJAX can be complex, libraries of functions can make it much easier. MediaWiki |
While programming AJAX can be complex, libraries of functions can make it much easier. Since the [[mw:MediaWiki 1.16|1.16 release]], MediaWiki comes with the [[jQuery]] library, which provides a convenient framework for easily making Ajax requests. Prior to version 1.17, MediaWiki provided [{{SERVER}}/skins-1.5/common/ajax.js ajax.js], containing a small set of functions by default. User scripts such as [[m:User:Pathoschild/Scripts/Ajax framework|Pathoschild's AJAX framework]] also provided a more comprehensive library of functions, but is now obsolete. The examples using these old methods are kept for historical reasons. |
||
==Common problems== |
==Common problems== |
||
* <p>AJAX programmers commonly run into problems if they don't account for AJAX's ''asynchronicity''. If you try to pop up a box with another page's content, you will almost certainly pop up a box containing <code>'''null'''</code>. This occurs because the script continued even though the query wasn't finished.</p><!-- |
* <p>AJAX programmers commonly run into problems if they don't account for AJAX's ''asynchronicity''. If you try to pop up a box with another page's content, you will almost certainly pop up a box containing <code>'''null'''</code>. This occurs because the script continued even though the query wasn't finished.</p><!-- |
||
--><p>To correct the problem, you need to use [[w:callback (computer science)|callback functions]]. Place the next portion of code after a query into a function, and call the function when the query completes. |
--><p>To correct the problem, you need to use [[w:callback (computer science)|callback functions]]. Place the next portion of code after a query into a function, and call the function when the query completes. jQuery makes this very easy to do.</p> |
||
* AJAX scripts cannot reach a page on a different server (for example, ''google.ca'' or ''en.wikisource.org'' from ''en.wikipedia.org''). Trying to do so will cause the script to halt with or without error. This can be circumvented using a proxy on the current server, but none is available for Wikimedia user scripts. |
* AJAX scripts cannot reach a page on a different server (for example, ''google.ca'' or ''en.wikisource.org'' from ''en.wikipedia.org''). Trying to do so will cause the script to halt with or without error. This can be circumvented using a proxy on the current server, but none is available for Wikimedia user scripts. |
||
== |
==jQuery examples== |
||
=== |
===Fetch page content=== |
||
Fetching a page content can be done using [[GET]]. |
|||
⚫ | Before you can query or fetch a page, you must create a query object. Different browsers use different objects, but MediaWiki provides the <code>sajax_init_object()</code> to do it in one step. The [[m:User:Pathoschild/Scripts/Ajax framework|AJAX framework]] equivalent is <code>ajax_create()</code>. |
||
<source lang="javascript"> |
|||
$.get('example.php', function(data) { |
|||
alert('The remote page contains:\n' + data); |
|||
}) |
|||
.error(function() { |
|||
alert('The query returned an error.'); |
|||
}); |
|||
</source> |
|||
===Edit a page and other common actions=== |
|||
⚫ | Scripts can perform common actions (like editing, protection, blocking, deletion, etc) through the [{{SERVER}}/w/api.php API]. These actions require an edit token, which is valid for any action during the same session. (However, you should get a new token for different tasks in case this changes in the future.) |
||
⚫ | |||
<source lang="javascript"> |
|||
$.getJSON( |
|||
mw.util.wikiScript( 'api' ), { |
|||
format: 'json', |
|||
action: 'query', |
|||
prop: 'info', |
|||
indexpageids: '1', |
|||
intoken: 'edit', |
|||
titles: 'Whatever' |
|||
}, |
|||
function( data ) { |
|||
var token = data.query.pages[ data.query.pageids[0] ].edittoken; |
|||
edit_page(token); |
|||
} |
|||
).error(function() { |
|||
alert( 'The token query returned an error. =(' ); |
|||
}); |
|||
// Edit page (must be done through POST) |
|||
function edit_page( token) { |
|||
var mySandbox = 'User:' + mw.config.get( 'wgUserName' ) + '/Sandbox'; |
|||
$.post( |
|||
mw.util.wikiScript( 'api' ), { |
|||
action: 'edit', |
|||
title: mySandbox, |
|||
text: 'Cool! It works! [[Image:Smile.png]]', |
|||
summary: 'Trying to edit my sandbox using AJAX...', |
|||
token: token |
|||
}, |
|||
function() { |
|||
alert( 'Page edited!' ); |
|||
} |
|||
).error(function() { |
|||
alert( 'The edit query returned an error. =(' ); |
|||
}); |
|||
} |
|||
</source> |
|||
==Deprecated methods == |
|||
===Create an AJAX object=== |
|||
⚫ | |||
⚫ | Before you can query or fetch a page, you must create a query object. Different browsers use different objects, but MediaWiki provides the <code>sajax_init_object()</code> to do it in one step. The [[m:User:Pathoschild/Scripts/Ajax framework|AJAX framework]] equivalent is <code>ajax_create()</code> (see [[#AJAX framework|section below]]). |
||
<source lang="javascript"> |
<source lang="javascript"> |
||
/************ |
|||
⚫ | |||
************/ |
|||
var query = sajax_init_object(); |
var query = sajax_init_object(); |
||
</source> |
|||
⚫ | |||
/************ |
|||
<source lang="javascript"> |
|||
⚫ | |||
************/ |
|||
var query = ajax_create(); |
var query = ajax_create(); |
||
</source> |
</source> |
||
Line 28: | Line 77: | ||
===Fetch page content=== |
===Fetch page content=== |
||
Fetching a page content can be done using [[GET]]. |
Fetching a page content can be done using [[GET]]. |
||
⚫ | |||
<source lang="javascript"> |
<source lang="javascript"> |
||
/************ |
|||
⚫ | |||
************/ |
|||
// fetch |
// fetch |
||
var api = sajax_init_object(); |
var api = sajax_init_object(); |
||
Line 48: | Line 96: | ||
} |
} |
||
} |
} |
||
</source> |
|||
⚫ | |||
/************ |
|||
<source lang="javascript"> |
|||
⚫ | |||
************/ |
|||
ajax_get('http://example.com', show_result); |
ajax_get('http://example.com', show_result); |
||
function show_result(_api) { |
function show_result(_api) { |
||
Line 63: | Line 111: | ||
===Edit a page and other common actions=== |
===Edit a page and other common actions=== |
||
⚫ | |||
⚫ | Scripts can perform common actions (like editing, protection, blocking, deletion, etc) through the [{{SERVER}}/w/api.php API]. These actions require an edit token, which is valid for any action during the same session. (However, you should get a new token for different tasks in case this changes in the future.) |
||
⚫ | |||
<source lang="javascript"> |
<source lang="javascript"> |
||
/************ |
|||
⚫ | |||
************/ |
|||
// fetch token |
// fetch token |
||
var api = sajax_init_object(); |
var api = sajax_init_object(); |
||
Line 110: | Line 153: | ||
} |
} |
||
} |
} |
||
</source> |
|||
⚫ | |||
/************ |
|||
<source lang="javascript"> |
|||
⚫ | |||
************/ |
|||
ajax_edit_token('edit', edit_page); |
ajax_edit_token('edit', edit_page); |
||
function edit_page(_token) { |
function edit_page(_token) { |
||
Line 147: | Line 190: | ||
==See also== |
==See also== |
||
* [[mw:ResourceLoader/JavaScript Deprecations#ajax.js]] |
|||
* [[mw:ResourceLoader/Default modules#jQuery & plugins]] |
|||
===Code=== |
===Code=== |
||
;User scripts |
;User scripts |
Revision as of 02:12, 25 July 2011
AJAX (asynchronous JavaScript and XML) is a popular name for a web programming technique that queries the server or fetches content without reloading the entire page.
While programming AJAX can be complex, libraries of functions can make it much easier. Since the 1.16 release, MediaWiki comes with the jQuery library, which provides a convenient framework for easily making Ajax requests. Prior to version 1.17, MediaWiki provided ajax.js, containing a small set of functions by default. User scripts such as Pathoschild's AJAX framework also provided a more comprehensive library of functions, but is now obsolete. The examples using these old methods are kept for historical reasons.
Common problems
AJAX programmers commonly run into problems if they don't account for AJAX's asynchronicity. If you try to pop up a box with another page's content, you will almost certainly pop up a box containing
null
. This occurs because the script continued even though the query wasn't finished.To correct the problem, you need to use callback functions. Place the next portion of code after a query into a function, and call the function when the query completes. jQuery makes this very easy to do.
- AJAX scripts cannot reach a page on a different server (for example, google.ca or en.wikisource.org from en.wikipedia.org). Trying to do so will cause the script to halt with or without error. This can be circumvented using a proxy on the current server, but none is available for Wikimedia user scripts.
jQuery examples
Fetch page content
Fetching a page content can be done using GET.
$.get('example.php', function(data) {
alert('The remote page contains:\n' + data);
})
.error(function() {
alert('The query returned an error.');
});
Edit a page and other common actions
Scripts can perform common actions (like editing, protection, blocking, deletion, etc) through the API. These actions require an edit token, which is valid for any action during the same session. (However, you should get a new token for different tasks in case this changes in the future.)
The code below shows how to edit a page, but it can easily be adapted to other actions by reading the API documentation.
$.getJSON(
mw.util.wikiScript( 'api' ), {
format: 'json',
action: 'query',
prop: 'info',
indexpageids: '1',
intoken: 'edit',
titles: 'Whatever'
},
function( data ) {
var token = data.query.pages[ data.query.pageids[0] ].edittoken;
edit_page(token);
}
).error(function() {
alert( 'The token query returned an error. =(' );
});
// Edit page (must be done through POST)
function edit_page( token) {
var mySandbox = 'User:' + mw.config.get( 'wgUserName' ) + '/Sandbox';
$.post(
mw.util.wikiScript( 'api' ), {
action: 'edit',
title: mySandbox,
text: 'Cool! It works! [[Image:Smile.png]]',
summary: 'Trying to edit my sandbox using AJAX...',
token: token
},
function() {
alert( 'Page edited!' );
}
).error(function() {
alert( 'The edit query returned an error. =(' );
});
}
Deprecated methods
Create an AJAX object
MediaWiki ajax.js
Before you can query or fetch a page, you must create a query object. Different browsers use different objects, but MediaWiki provides the sajax_init_object()
to do it in one step. The AJAX framework equivalent is ajax_create()
(see section below).
var query = sajax_init_object();
AJAX framework
var query = ajax_create();
Fetch page content
Fetching a page content can be done using GET.
MediaWiki ajax.js
// fetch
var api = sajax_init_object();
api.open('GET', 'http://example.com', true);
api.onreadystatechange = show_result;
api.send(null);
// handle response
function show_result(_api) {
if(_api.readyState==4) {
if(_api.status==200) {
alert('The remote page contains:\n' + _api.responseText);
} else {
alert('The query returned an error.');
}
}
}
AJAX framework
ajax_get('http://example.com', show_result);
function show_result(_api) {
if(_api.ajax_success) {
alert('The remote page contains:\n' + _api.responseText);
} else {
alert('An error occurred.');
}
}
Edit a page and other common actions
MediaWiki ajax.js
// fetch token
var api = sajax_init_object();
api.open('GET', wgServer + wgScriptPath + '/api.php?format=json&action=query&prop=info&indexpageids=1&intoken=edit&titles=Whatever', true);
api.onreadystatechange = extract_token;
api.send(null);
function extract_token() {
if(api.readyState==4) {
if(api.status==200) {
var response = eval('(' + api.responseText + ')');
var token = response['query']['pages'][response['query']['pageids'][0]]['edittoken'];
edit_page(token);
}
else {
alert('The token query returned an error.');
}
}
}
// edit page (must be done through POST)
function edit_page(_token) {
var parameters = 'action=edit&title=User:Pathoschild/Sandbox&text=AJAX_test!&token=' + encodeURIComponent(_token);
api.open('POST', wgServer + wgScriptPath + '/api.php', true); // just reuse the same query object
api.onreadystatechange = alert_result;
api.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
api.setRequestHeader('Connection', 'keep-alive');
api.setRequestHeader('Content-length', parameters.length);
api.send(parameters);
// process response
function alert_result() {
if(api.readyState==4) {
if(api.status==200) {
alert('Page edited!');
}
else {
alert('The query returned an error.');
}
}
}
}
AJAX framework
ajax_edit_token('edit', edit_page);
function edit_page(_token) {
var parameters = 'action=edit&title=User:Pathoschild/Sandbox&text=AJAX_test!&token=' + encodeURIComponent(_token);
ajax_post(wgServer + wgScriptPath + '/api.php', parameters, alert_result);
}
function alert_result(_api) {
if(_api.ajax_success) {
alert('Page edited!');
} else {
alert('An error occurred.');
}
}
Data sources
api.php
See mw:API. Usually used with JSON format.
HTML
You could fetch the whole article page or use &action=render
URL parameter to get the content without all the menus (example). Also see Parameters to index.php.
The result you could treat as a text but it's usually convenient to parse it as HTML document, e.g. using DOMParser object (examples needed).
Wiki code
To get the wiki code you use &action=raw
URL parameter (example).
The result you treat as a text.
Preview
Sometimes you might want to use preview. For example, Special:Prefixindex won't work with &action=render
. To get rid of the unnecessary menus you could submit {{Special:Prefixindex/somepage}} for a preview and get a "clean" list (nevertheless, it's better to use API for prefix index)
See also
- mw:ResourceLoader/JavaScript Deprecations#ajax.js
- mw:ResourceLoader/Default modules#jQuery & plugins
Code
- User scripts
-
- Comprehensive AJAX framework (by Pathoschild)
- AJAX editing (by TheFearow)
- Ajax preview (by Alex Smotrov)
- Ajax unwatch from watchlist (by Alex Smotrov)
- Various code with AJAX
- Navigation popups
- Twinkle (some code in User:AzaToth/morebits.js, and good examples of AJAX are in the bottom of User:AzaToth/twinklespeedy.js)
- User:Kaldari/wikilove.js - uses Ajax (via jQuery) to edit user talk pages
- Mediawiki
-
- ajax.js - some support functions
- ajaxwatch.js - watch/unwatch
- upload.js - licenses preview on Special:Upload
- Internal and disabled code
- AjaxFunctions.php has 2 main functions:
- wfAjaxWatch - server part of ajaxwatch.js
- wfSajaxSearch - disabled on WMF projects. If it was enabled, ajaxsearch.js would be responsible for the client side. Also see mw:Manual:$wgAjaxSearch.
- Live preview (preview.js)
- AjaxFunctions.php has 2 main functions:
Alternatives
- IFrames are an obsolete older method (see a small untested library by TheFearow)
- URL parameters: a script can call itself on a different by adding a custom URL parameter to the address bar. It can then check the address bar on every page load, and run code depending on the values of the custom headers. See an example unmaintaned library by Lupin).