.. include:: /Includes.rst.txt .. index:: Ajax; Request .. _ajax-request: ============ 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 ================= .. versionadded:: 13.0 Native URL-related objects (:js:`URL` and :js:`URLSearchParams`) can be used. To be able to send a request, the module :js:`@typo3/core/ajax/ajax-request.js` must be imported. To prepare a request, create a new instance of :js:`AjaxRequest` per request and pass the URL as the constructor argument: .. literalinclude:: _MyRequest1.js :language: js :caption: EXT:my_extension/Resources/Private/JavaScript/MyRequest.js The API offers a method :js:`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 :js:`AjaxRequest` object. It is possible to pass either strings, arrays or objects as an argument. Example: .. literalinclude:: _MyRequest2.js :language: js :caption: EXT:my_extension/Resources/Private/JavaScript/MyRequest.js 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: * :js:`get()` * :js:`post()` * :js:`put()` * :js:`delete()` Each of these methods set the corresponding request method (GET, POST, PUT, DELETE). :js:`post()`, :js:`put()` and :js:`delete()` accept the following arguments: .. option:: data :Required: true :type: string | object The payload to be sent as body in the request. .. option:: init :Required: false :type: object :Default: :js:`{}` Additional `request configuration`_ to be set. The method :js:`get()` accepts the :js:`init` argument only. Example: .. code-block:: js let promise = request.get(); .. note:: The API presets the request configuration with :js:`{credentials: 'same-origin', signal: AbortController.signal}`. 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: .. literalinclude:: _MyRequestPromise1.js :language: js :caption: EXT:my_extension/Resources/Private/JavaScript/MyRequest.js .. index:: Ajax; Response Handle the response =================== In the examples above :js:`promise` is, as the name already spoils, a `Promise`_ object. To fetch the actual response, we make use of :js:`then()`: .. literalinclude:: _MyRequestPromise2.js :language: js :caption: EXT:my_extension/Resources/Private/JavaScript/MyRequest.js :js:`response` is an object of type :js:`AjaxResponse` shipped by TYPO3 (:js:`@typo3/core/ajax/ajax-response.js`). The object is a simple wrapper for the original `Response`_ object. :js:`AjaxResponse` exposes the following methods which eases the handling of responses: :js:`resolve()` Returns the correct response based on the received `Content-Type` header, either plaintext or a JSON object. :js:`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 :js:`then()`, which handles the exceptional case. The function may receive a :js:`AjaxResponse` object which contains the original response object. .. literalinclude:: _MyRequestPromise3.js :language: js :caption: EXT:my_extension/Resources/Private/JavaScript/MyRequest.js .. hint:: The fetch API handles responses with faulty statuses like 404 or 500 still as "successful", but sets the response's :js:`ok` field to :js:`false`. The Ajax API converts such responses into errors for convenience reasons. .. index:: Ajax; Abort 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 :js:`abort()` method: .. code-block:: js request.abort(); .. _`fetch API`: https://developer.mozilla.org/docs/Web/API/Fetch_API .. _`request configuration`: https://developer.mozilla.org/en-US/docs/Web/API/Request#Properties .. _`Response`: https://developer.mozilla.org/en-US/docs/Web/API/Response .. _`Promise`: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise .. _`FormData`: https://developer.mozilla.org/en-US/docs/Web/API/FormData .. _`AbortController`: https://developer.mozilla.org/en-US/docs/Web/API/AbortController