Ajax request

TYPO3 Core ships an API to send Ajax requests to the server. This API is based on the fetch API, which is implemented in every modern browser (for example, Chrome, Edge, Firefox, Safari).

Prepare a request

New in version 13.0

Native URL-related objects (URL and URLSearchParams) can be used.

To be able to send a request, the module @typo3/core/ajax/ajax-request.js must be imported. To prepare a request, create a new instance of AjaxRequest per request and pass the URL as the constructor argument:

EXT:my_extension/Resources/Private/JavaScript/MyRequest.js
import AjaxRequest from "@typo3/core/ajax/ajax-request.js";

let url = 'https://example.org/my-endpoint';
// or:
let url = new URL('https://example.org/my-endpoint');

let request = new AjaxRequest(url);
Copied!

The API offers a method withQueryArguments() which allows to attach a query string to the URL. This comes in handy, if the query string is programmatically generated. The method returns a clone of the AjaxRequest object. It is possible to pass either strings, arrays or objects as an argument.

Example:

EXT:my_extension/Resources/Private/JavaScript/MyRequest.js
import AjaxRequest from "@typo3/core/ajax/ajax-request.js";

let request = new AjaxRequest('https://example.org/my-endpoint');

let queryArguments = {
  foo: 'bar',
  bar: {
    baz: ['foo', 'bencer']
  }
};
// or:
let queryArguments = new URLSearchParams({
  foo: 'bar',
  baz: {
    baz: ['foo', 'bencer']
  }
});

request = request.withQueryArguments(queryArguments);

// The query string compiles to ?foo=bar&bar[baz][0]=foo&bar[baz][1]=bencer
Copied!

The method detects whether the URL already contains a query string and appends the new query string in a proper format.

Send a request

The API offers some methods to actually send the request:

  • get()
  • post()
  • put()
  • delete()

Each of these methods set the corresponding request method (GET, POST, PUT, DELETE). post(), put() and delete() accept the following arguments:

data
Required

true

type

string | object

The payload to be sent as body in the request.

init
Required

false

type

object

Default

{}

Additional request configuration to be set.

The method get() accepts the init argument only.

Example:

let promise = request.get();
Copied!

The body of the request is automatically converted to a FormData object, if the submitted payload is an object. To send a JSON-encoded object instead, set the Content-Type header to application/json. If the payload is a string, no conversion will happen, but it is still recommended to set proper headers.

Example:

EXT:my_extension/Resources/Private/JavaScript/MyRequest.js
import AjaxRequest from "@typo3/core/ajax/ajax-request.js";

let request = new AjaxRequest('https://example.org/my-endpoint');

const json = {foo: 'bar'};
let promise = request.post(json, {
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
});
Copied!

Handle the response

In the examples above promise is, as the name already spoils, a Promise object. To fetch the actual response, we make use of then():

EXT:my_extension/Resources/Private/JavaScript/MyRequest.js
import AjaxRequest from "@typo3/core/ajax/ajax-request.js";

let request = new AjaxRequest('https://example.org/my-endpoint');

const json = {foo: 'bar'};
let promise = request.post(json, {
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
});

promise.then(async function (response) {
  const responseText = await response.resolve();
  console.log(responseText);
});
Copied!

response is an object of type AjaxResponse shipped by TYPO3 (@typo3/core/ajax/ajax-response.js). The object is a simple wrapper for the original Response object. AjaxResponse exposes the following methods which eases the handling of responses:

resolve()
Returns the correct response based on the received Content-Type header, either plaintext or a JSON object.
raw()
Returns the original Response object.

Of course, a request may fail for various reasons. In such case, a second function may be passed to then(), which handles the exceptional case. The function may receive a AjaxResponse object which contains the original response object.

EXT:my_extension/Resources/Private/JavaScript/MyRequest.js
import AjaxRequest from "@typo3/core/ajax/ajax-request.js";

let request = new AjaxRequest('https://example.org/my-endpoint');

const json = {foo: 'bar'};
let promise = request.post(json, {
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
});

promise.then(async function (response) {
}, function (error) {
  console.error(`The request failed with ${error.response.status}: ${error.response.statusText}`);
});
Copied!

Abort a request

In some cases it might be necessary to abort a running request. The Ajax API has you covered them, an instance of AbortController is attached to each request. To abort the request, just call the abort() method:

request.abort();
Copied!