---
title: "Ajax in the backend, client-side"
manual: "TYPO3 Explained"
version: "11.5"
permalink: "https://docs.typo3.org/permalink/t3coreapi:ajax-client-side@11.5"
source: "ApiOverview/Backend/AjaxClientSide.rst"
rendered: "2026-10-21T15:30:00+00:00"
---

> [!WARNING]
> **Attention**
>
> TYPO3 v11 has reached end-of-life as of October 31th 2024 and
> is no longer being maintained. Use the version switcher on the top
> left of this page to select documentation for a supported version of TYPO3.
>
> Need more time before upgrading?
> You can purchase Extended Long Term Support (ELTS) for TYPO3 v11 here:
> [TYPO3 ELTS](https://typo3.com/services/extended-support-elts).

# Ajax in the backend, client-side {#ajax-client-side}

TYPO3 Core ships an API to send Ajax requests to the server. This API is based on the [fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API), which is implemented
in every modern browser (e.g. Chrome, Safari, Firefox, Edge).

> [!NOTE]
> TYPO3 ships jQuery as well, but is considered discouraged for new code.

## Prepare a request {#prepare-a-request}

To be able to send a request, the module `TYPO3/CMS/Core/Ajax/AjaxRequest` must be imported. To prepare a request,
create a new instance of `AjaxRequest` per request and pass the url as the constructor argument:

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

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's possible
to pass either strings, arrays or objects as an argument.

Example:

```js
const qs = {
  foo: 'bar',
  bar: {
    baz: ['foo', 'bencer']
  }
};
request = request.withQueryArguments(qs);

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

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

## Send a Request {#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**

    `|` *Condition:* required
    `|` *Type:* string | object
    `|`

    The payload to be sent as body in the request.

-   **init**

    `|` *Condition:* optional
    `|` *Type:* object
    `|` *Default:* '{}'
    `|`

    Additional [request configuration](https://developer.mozilla.org/en-US/docs/Web/API/Request#Properties) to be set

The method `get()` accepts the `init` argument only.

Example:

```js
let promise = request.get();
```

> [!NOTE]
> The API presets the request configuration with `{credentials: 'same-origin', signal: AbortController.signal}`.

The body of the request is automatically converted to a [FormData](https://developer.mozilla.org/en-US/docs/Web/API/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's still recommended to set proper headers.

Example:

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

## Handle the response {#handle-the-response}

In the examples above `promise` is, as the name already spoils, a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object. To fetch the actual response,
we'll make use of `then()`:

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

`response` is an object of type `AjaxResponse` shipped by TYPO3 (`TYPO3/CMS/Core/Ajax/AjaxResponse`). The
object is a simple wrapper for the original [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object. `AjaxResponse` exposes the following methods which
eases the handling with responses:

-   `resolve()` \- returns the correct response based on the received `Content-Type` header, either plaintext or a JSON object
-   `raw()` \- returns the original [Response](https://developer.mozilla.org/en-US/docs/Web/API/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 `ResponseError` object (`TYPO3/CMS/Core/Ajax/ResponseError`)
which contains the received response.

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

> [!TIP]
> **Hint**
>
> The fetch API handles responses with faulty statuses like 404 or 500 still as "successful", but sets the response's
> `ok` field to `false`. The Ajax API converts such responses into errors for convenience reasons.

## Abort a request {#abort-a-request}

In some cases it might be necessary to abort a running request. The Ajax API has you covered then, an instance of
[AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) is attached to each request. To abort the request, just call the `abort()` method:

```js
request.abort();
```
