AJAX 请求(JavaScript API)

Introduction

Snowboard 通过以下方式提供核心 AJAX 功能Request 滑雪板插件。这Request 插件在Winter使用后端功能发出 AJAX 请求时提供了强大的灵活性和可重用性。可以通过将以下标记添加到 CMS 主题的页面或布局中来加载它:

{% snowboard request %}

并在您的 JavaScript 中使用以下代码调用:

Snowboard.request('#element', 'onAjax', {});

基地Request 插件使用获取API 在大多数现代浏览器中提供,以在Winter执行从前端到后端的 AJAX 请求。

NOTE: 如果您想替换基础功能的任何部分Request 插件然后你可以写一个自定义滑雪板插件 扩展并覆盖基础Request 插件以根据需要对其进行自定义。

request 方法接受三个参数:

Parameter Required Description
element No 此 AJAX 请求所针对的元素,可以是HTMLElement 实例,或作为 CSS 选择器字符串。这可以是任何元素,但通常与form 元素。
handler Yes 要调用的 AJAX 处理程序。这应该是格式on<Handler>.
options No AJAX 请求选项, 作为一个对象。

请求工作流

AJAX 请求通过Request 类经历以下过程:

可用选项

以下所有选项都是可选的。

Option Type Description
confirm string 如果提供,用户将收到此确认消息提示,并需要确认他们是否希望继续请求。
data Object 如果可用,将与任何表单数据一起发送到服务器的额外数据。如果filestrue,您还可以通过使用在请求中包含文件Blob 对象.
redirect string 如果提供,浏览器将在请求成功完成后重定向到此 URL。
form HTMLElement 或者string 指定将从中提取数据并在请求中发送数据的表单。如果未提供,表单将根据请求提供的元素自动确定。如果没有给出元素,则不会使用任何形式。
files boolean 如果true,此请求将接受数据中的文件上传。
browserValidate boolean 如果true,大多数常见浏览器提供的内置客户端验证将在发送请求之前执行。这仅适用于请求中使用表单的情况。
flash boolean 如果true, 请求将处理并显示响应中返回的任何即显消息。
update Object 指定可通过 AJAX 响应更改的部分和页面元素列表。对象的键表示部分名称,值表示要作为更新目标的页面元素(作为 CSS 选择器)。如果选择器字符串前面有一个@ 符号,内容将附加到目标。如果选择器字符串前面有^ 符号,它将被添加到目标中。
fetchOptions Object 如果指定,这将覆盖与获取API 提出请求。

还可以在以下回调中指定options 范围。所有回调都期望提供一个函数。这this所有回调中的关键字将被分配Request 表示当前 AJAX 请求的实例。

Callback Description
beforeUpdate 在使用响应数据更新页面元素之前执行。该函数接收一个参数:来自 AJAX 响应的响应数据作为对象。
success 当成功响应 AJAX 请求时执行。该函数接收两个参数:作为对象的 AJAX 响应的响应数据,以及Request 实例。
error 当 AJAX 请求由于服务器端错误或验证错误而失败时执行。该函数接收两个参数:作为对象的 AJAX 响应的响应数据,以及Request 实例。
complete 在 AJAX 请求完成时执行,无论成功或失败。该函数接收两个参数:作为对象的 AJAX 响应的响应数据,以及Request 实例。

最后,以下选项参数定义了各种操作的覆盖功能Request 实例可能在处理响应期间发生。与回调方法一样,这些方法必须作为函数提供。

Option Parameters Description
handleConfirmMessage (string) confirmationMessage 处理用户请求的任何确认。
handleErrorMessage (string) errorMessage 处理请求期间发生的任何错误
handleValidationMessage (string) message, (Object) fieldMessages 处理请求期间发生的验证错误。fieldMessages 以字段名称作为键,以消息作为值。
handleFlashMessage (string) message, (string) type 处理 flash 消息。
handleRedirectResponse (string) redirectUrl 处理重定向响应。

全球事件

Request 类触发几个全局事件,插件可以使用这些事件来增强或覆盖类的功能Request 班级。滑雪板插件 可以配置为通过使用listen() 方法将事件定向到具有插件类的方法。

class HandleFlash extends Snowboard.Singleton
{
    /**
     * Defines listeners for global events.
     *
     * @returns {Object}
     */
    listens() {
        return {
            // when the "ajaxFlashMessages" event is called, run the "doFlashMessage" method in this class
            ajaxFlashMessages: 'doFlashMessages',
        };
    }

    doFlashMessages(messages) {
        Object.entries(messages).forEach((entry) => {
            const [cssClass, message] = entry;

            showFlash(message, cssClass);
        });
    }
}

有些事件称为 Promise 事件,这意味着您的侦听器本身必须返回一个Promise 这要么被解决,要么被拒绝。

class ConfirmEverything extends Snowboard.Singleton
{
    /**
     * Defines listeners for global events.
     *
     * @returns {Object}
     */
    listens() {
        return {
            // when the "ajaxConfirmMessage" event is called, run the "confirm" method in this class
            ajaxConfirmMessage: 'confirm',
        };
    }

    // Confirm all confirmation messages
    confirm() {
        return Promise.resolve(true);
    }
}

Request过程中会调用以下事件:

Event Promise? Parameters Description
ajaxSetup No (Request) request 在 Request 初始化并检查是否可以调用后调用。它旨在用于在发送到服务器之前修改请求参数。回归false 在任何情况下,听众都会取消请求。
ajaxConfirmMessage Yes (Request) request, (string) confirmationMessage 如果调用confirm 已指定,请求已准备好发送到服务器。这允许开发人员自定义确认过程或显示。如果事件侦听器拒绝 Promise,这将取消请求。
ajaxBeforeSend No (Request) request 在发送请求之前立即调用。它可用于对请求进行最终更改,或提前取消请求。回归false 在任何情况下,听众都会取消请求。
ajaxFetchOptions No (Object) fetchOptions, (Request) request 时立即调用Fetch API 被初始化以发出请求。它可用于通过插件修改 Fetch 选项。此事件无法取消。
ajaxStart No (Promise) callback, (Request) request 发送请求时调用。此事件无法取消。
ajaxBeforeUpdate Yes (mixed) response, (Request) request 当返回成功的响应并且将要更新部分时调用。它可用于确定将更新哪些部分,也可用于取消部分更新。如果事件侦听器拒绝 Promise,则不会更新任何部分。
ajaxUpdate No (HTMLElement) element, (string) content, (Request) request 在更新单个部分时调用。它可用于对元素进行进一步更新或处理更新。请注意,此事件已触发after 元素已更新。此事件无法取消。
ajaxUpdateComplete No (array of HTMLElement) elements, (Request) request) 部分更新时调用。它可用于确定哪些部分已更新。此事件无法取消。
ajaxSuccess No (Object) responseData, (Request) request 当返回成功响应且所有部分更新完成时调用。它可用于取消进一步的响应处理(即重定向、闪存消息)。回归false 在任何情况下,监听器都会阻止任何进一步的响应处理发生。
ajaxError No (Object) responseData, (Request) request 当从 AJAX 请求返回不成功的响应时调用。它可用于取消进一步的错误处理。回归false 在任何情况下,监听器都会阻止任何进一步的响应处理发生。
ajaxRedirect No (string) redirectUrl, (Request) request 在发生重定向时调用,无论是从响应还是通过redirect 选项。回归false 在任何情况下,监听器都会阻止重定向的执行。
ajaxErrorMessage No (string) message, (Request) request 当向用户显示错误消息时调用。回归false在任何情况下,侦听器都会阻止执行默认的错误处理(向用户显示警报)。
ajaxFlashMessages No (array of Object) flashMessages, (Request) request 当要向用户显示一条或多条即显消息时调用。即时消息没有默认功能,因此如果没有事件侦听器触发此事件,则不会发生任何活动。
ajaxValidationErrors No (HTMLElement) form, (array) fieldMessages, (Request) request 在响应中返回验证错误时调用。验证错误没有默认功能,因此如果没有事件侦听器触发此事件,则不会发生任何活动。

元素事件

除了全局事件之外,还会在触发 AJAX 请求的元素上触发本地事件。这些事件被视为DOM 事件 因此可以被普通的 DOM 事件监听器或您选择的框架监听。这Request 类将根据事件的类型和event.request 财产永远是Request 实例。

const element = document.getElementById('my-button');
element.addEventListener('ajaxAlways', (event) => {
    console.log(event.request); // The Request instance
    console.log(event.responseData); // The raw response data as an object
    console.log(event.responseError); // An error object if the response failed
});

在大多数情况下,您可以取消事件,从而取消请求,方法是添加event.preventDefault() 到你的回调。

const element = document.getElementById('my-button');
element.addEventListener('ajaxSetup', (event) => {
    // Never process a request for this element
    event.preventDefault();
});

在请求过程中直接在触发请求的元素上调用以下事件:

Event Description
ajaxSetup 在 Request 初始化并检查是否可以调用后调用。
ajaxPromise 当 AJAX 请求发送到服务器时调用。一个名为promise provided,即响应成功或失败时resolved或rejected的Promise。
ajaxUpdate 当通过 AJAX 响应的部分更新更新元素时​​调用。此事件在更新的元素上触发,而不是触发元素。 因此没有得到Request 实例。一个名为content 随添加到此元素的内容一起提供。
ajaxDone 在此元素发出成功的 AJAX 请求时调用。一个名为responseData 作为对象提供原始响应数据。
ajaxFail 在此元素发出不成功的 AJAX 请求时调用。一个名为responseError 随错误对象一起提供。
ajaxAlways 在 AJAX 请求完成时调用,无论成功或失败。它提供了两个属性:responseDataresponseError,表示原始响应数据和错误对象,具体取决于 AJAX 请求是成功还是失败。

使用示例

在不指定触发元素的情况下向 AJAX 处理程序发出简单请求。

Snowboard.request(null, 'onAjax');

在提交表单之前请求确认,并将它们重定向到成功页面。

Snowboard.request('form', 'onSubmit', {
    confirm: 'Are you sure you wish to submit this data?',
    redirect: '/form/success',
});

运行计算处理程序并从页面注入一些数据,然后更新总数。

Snowboard.request('#calculate', 'onCalculate', {
    data: {
        firstValue: document.getElementById('first-value').value,
        secondValue: document.getElementById('second-value').value,
    },
    update: {
        totalResult: '.total-result'
    },
});

运行计算处理程序并在计算时显示成功消息。

Snowboard.request('#calculate', 'onCalculate', {
    data: {
        firstValue: document.getElementById('first-value').value,
        secondValue: document.getElementById('second-value').value,
    },
    success: (data) => {
        const total = data.total;
        alert('The answer is ' + total);
    },
});

提示用户确认重定向。

Snowboard.request('form', 'onSubmit', {
    handleRedirectResponse: (url) => {
        if (confirm('Are you sure you wish to go to this URL: ' + url)) {
            window.location.assign(url);
        } else {
            alert('Redirect cancelled');
        }
    },
});

跟踪元素何时从 AJAX 请求更新。

const element = document.getElementById('updated-element');
element.addEventListener('ajaxUpdate', (event) => {
    console.log('The "updated-element" event was updated with the following content:', event.content);
});

通过修改 AJAX 请求全局禁用文件上传Request 实例。

// In your own Snowboard plugin
class DisableFileUploads extends Snowboard.Singleton
{
    listens() {
        return {
            ajaxSetup: 'stopFileUploads',
        };
    }

    stopFileUploads(request) {
        request.options.files = false;
    }
}

扩展或替换 Request 类

作为使 Snowboard 成为可扩展和灵活平台的一部分,开发人员可以选择扩展或完全替换基本 Request 类。这允许开发人员使用他们自己喜欢的平台和框架来执行 AJAX 功能、部分更新等。

例如,如果开发人员想使用axios库 要执行 AJAX 请求,而不是内置的 Fetch API,可以通过创建自己的 Snowboard 插件并扩展Request 类,替换doAjax() 在他们自己的类中的方法:

const axios = require('axios');

class AxiosRequest extends Request
{
    doAjax() {
        // Allow plugins to cancel the AJAX request before sending
        if (this.snowboard.globalEvent('ajaxBeforeSend', this) === false) {
            return Promise.resolve({
                cancelled: true,
            });
        }

        const ajaxPromise = axios({
            method: 'post',
            url: this.url,
            headers: this.headers,
            data: this.data,
        });

        this.snowboard.globalEvent('ajaxStart', ajaxPromise, this);

        if (this.element) {
            const event = new Event('ajaxPromise');
            event.promise = ajaxPromise;
            this.element.dispatchEvent(event);
        }

        return ajaxPromise;
    }
}

然后你可以替换request 使用此类插件,或将其别名为其他名称:

Snowboard.removePlugin('request');
Snowboard.addPlugin('request', AxiosRequest);

// Or run it as an alias
Snowboard.addPlugin('axios', AxiosRequest);
// And call it thusly
Snowboard.axios('#my-element', 'onSubmit');

有关设置 Snowboard 插件的最佳实践的更多信息,请查看插件开发 文档。

豫ICP备18041297号-2