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
类经历以下过程:
- 使用给定的元素和选项初始化和验证请求。
- 如果
browserValidate
已启用且 AJAX 请求已通过表单完成,将进行浏览器端验证。如果失败,请求将被取消。 - 如果
confirm
指定后,将向用户显示确认信息。如果他们取消,请求将被取消。 - 提供给请求的数据以及任何适用的表格数据将被编译。
- AJAX 请求使用给定的处理程序.
- 从后端上下文接收到响应并进行处理,从这里发生以下三种情况之一:
- 如果响应成功,则此时将更新指示更新的任何部分。
- 如果由于验证错误导致响应不成功,则会显示验证消息并突出显示失败的字段。
- 如果由于任何其他错误导致响应不成功,则会显示一条错误消息。
- 然后请求完成。
可用选项
以下所有选项都是可选的。
Option | Type | Description |
---|---|---|
confirm |
string |
如果提供,用户将收到此确认消息提示,并需要确认他们是否希望继续请求。 |
data |
Object |
如果可用,将与任何表单数据一起发送到服务器的额外数据。如果files 是true ,您还可以通过使用在请求中包含文件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 请求完成时调用,无论成功或失败。它提供了两个属性:responseData 和responseError ,表示原始响应数据和错误对象,具体取决于 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 插件的最佳实践的更多信息,请查看插件开发 文档。