Wikipedia:WikiProject User scripts/Guide/Ajax: Difference between revisions

Content deleted Content added
jQuery
 
(32 intermediate revisions by 10 users not shown)
Line 1:
#REDIRECT [[Wikipedia:User scripts/Guide]]
{{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.
 
While programming AJAX can be complex, libraries of functions can make it much easier. MediaWiki's [{{SERVER}}/skins-1.5/common/ajax.js ajax.js] provides a small set of functions by default<s>, and [[m:User:Pathoschild/Scripts/Ajax framework|Pathoschild's AJAX framework]] provides a more comprehensive library of functions</s><sup>(obsolete)</sup>. This page will document programming with and without the latter. In addition, [[jQuery]] provides a convenient framework for easily making Ajax requests.
 
==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>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. (The [[m:User:Pathoschild/Scripts/Ajax framework|AJAX framework]] 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.
 
==Code==
===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>.
 
<source lang="javascript">
/************
* MediaWiki ajax.js
************/
var query = sajax_init_object();
 
/************
* AJAX framework
************/
var query = ajax_create();
</source>
 
===Fetch page content===
Fetching a page content can be done using [[GET]].
<source lang="javascript">
/************
* 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.');
}
}
</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.)
 
The code below shows how to edit a page, but it can easily be adapted to other actions by reading the [{{SERVER}}/w/api.php API documentation].
<source lang="javascript">
/************
* 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.');
}
}
</source>
 
==Data sources==
 
===[{{SERVER}}{{SCRIPTPATH}}/api.php api.php]===
See [[mw:API]]. Usually used with [[JSON]] format.
 
===HTML===
You could fetch the whole article page or use <code>&action=render</code> URL parameter to get the content without all the menus ([{{fullurl:{{FULLPAGENAME}}|action=render}} example]). Also see [[mw:Manual:Parameters to index.php|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 <small>(examples needed)</small>.
 
===Wiki code===
To get the wiki code you use <code>&action=raw</code> URL parameter ([{{fullurl:{{FULLPAGENAME}}|action=raw}} example]).
 
The result you treat as a text.
 
===Preview===
Sometimes you might want to use preview. For example, [[Special:Prefixindex]] won't work with <code>&action=render</code>. To get rid of the unnecessary menus you could submit <tt><nowiki>{{Special:Prefixindex/somepage}}</nowiki></tt> for a preview and get a "clean" list (nevertheless, it's better to use API for prefix index)
 
==See also==
===Code===
;User scripts
:* [[m:User:Pathoschild/Scripts/Ajax framework|Comprehensive AJAX framework]] (by [[user:Pathoschild|Pathoschild]])
:* [[User:TheFearow/simpleajax.js|AJAX editing]] (by [[user:TheFearow|TheFearow]])
:* [[User talk:Alex Smotrov/qpreview.js|Ajax preview]] (by [[user:Alex Smotrov|Alex Smotrov]])
:* [[User talk:Alex Smotrov/wlunwatch.js|Ajax unwatch from watchlist]] (by [[user:Alex Smotrov|Alex Smotrov]])
:* Various code with AJAX
:** [[Wikipedia:Tools/Navigation popups|Navigation popups]]
:** [[Wikipedia:WikiProject User scripts/Scripts/Twinkle|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
:* [{{SERVER}}/skins-1.5/common/ajax.js ajax.js] - some support functions
:* [{{SERVER}}/skins-1.5/common/ajaxwatch.js ajaxwatch.js] - watch/unwatch
:* [{{SERVER}}/skins-1.5/common/upload.js upload.js] - licenses preview on [[Special:Upload]]
:* Internal and disabled code
:** [http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/AjaxFunctions.php?view=markup AjaxFunctions.php] has 2 main functions:
:**: wfAjaxWatch - server part of ajaxwatch.js
:**: wfSajaxSearch - disabled on WMF projects. If it was enabled, [{{SERVER}}/skins-1.5/common/ajaxsearch.js ajaxsearch.js] would be responsible for the client side. Also see [[mw:Manual:$wgAjaxSearch]].
:** [[mw:Manual:Live preview|Live preview]] ([{{SERVER}}/skins-1.5/common/preview.js preview.js])
 
===Alternatives===
* [[IFrame]]s are an obsolete older method (see [[User:TheFearow/ajax.js|a small untested library]] by [[user:TheFearow|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 [[User:Lupin/autoedit.js|an example unmaintaned library]] by [[user:Lupin|Lupin]]).