Фоновый скрипт
Фоновые скрипты подходят для сценариев, которые должны работать постоянно. Это тип скрипта, специфичный для ScriptCat: они выполняются в песочнице и не имеют доступа к DOM. Их можно разрабатывать с теми же GM API, что и в Tampermonkey; замечания по совместимости отмечены в документации.
Фоновый скрипт (@background)
Фоновый скрипт объявляется атрибутом @background. Он позволяет скрипту продолжать работу в фоне после включения скрипта или запуска браузера.
Скрипт по расписанию (@crontab)
Скрипт по расписанию — разновидность фонового скрипта, подходящая для задач, которые нужно выполнять повторно по временному циклу.
Скрипт по расписанию объявляется атрибутом @crontab. Поддерживается минутное и секундное планирование, а также расширенный синтаксис ScriptCat once / once(...), чтобы не запускаться более одного раза в пределах одного временного цикла.
⚠️ Замечания:
- В одном скрипте действует только первый
@crontab - Рекомендуется, чтобы время одного выполнения + время повтора не превышало интервал cron, иначе запуски могут пересекаться
Замечания по cron-выражениям
Реализация cron в ScriptCat основана на node-cron с небольшим расширением стандартного синтаксиса cron.
Формат выражения
Стандартный формат из 5 полей (рекомендуется)
minute hour day month weekday
Расширенный формат из 6 полей (не рекомендуется)
second minute hour day month weekday
⚠️ Формат из 6 полей не рекомендуется В среде браузера нельзя гарантировать секундную точность, и это увеличивает накладные расходы — планирование фоновой страницы может задерживаться.
Синтаксис, доступный в каждом поле
| Синтаксис | Значение | Пример |
|---|---|---|
* | Любое значение | * (каждую минуту/час) |
| число | Конкретное значение | 5 (5-я минута) |
a,b,c | Несколько дискретных значений | 1,15,30 |
a-b | Непрерывный диапазон | 10-23 |
*/n | Каждые n единиц | */5 |
a-b/n | Диапазон с шагом | 10-50/10 |
Правила для дня недели
1–6: понедельник — суббота0или7: воскресенье
Расширенный синтаксис once
Что означает once
Использование once в cron-выражении означает:
В текущем временном цикле допускается только одно успешное выполнение
Даже если более поздние моменты времени в том же цикле по-прежнему соответствуют правилу cron, скрипт снова не запустится.
once и once(...)
| Синтаксис | Базовое значение cron для этого поля | Описание |
|---|---|---|
once | * (любое значение) | Запуск при первом совпадении в цикле, без конкретного времени |
once(expr) | expr | Запуск только в моменты, соответствующие expr в цикле, и только один раз |
once(expr) позволяет точно указать кандидаты по времени, сохраняя правило «не более одного раза за цикл». Внутри скобок поддерживается весь стандартный синтаксис cron (числа, диапазоны, шаги, списки).
Сравнение примеров:
* once * * * // any minute of every hour; runs on the first match, no further runs that hour
* once(9-17) * * * // between 9:00 and 17:59 every day, runs once per hour
0,30 once * * * // whichever of minute 0 or 30 is matched first each hour runs; no further runs that hour
Позиция once = ограничиваемый временной цикл
Где бы ни стояли once / once(...), это означает «запускать только один раз в пределах этой временной гранулярности».
Позиция once | Поведение |
|---|---|
| поле минуты | Не более одного раза в минуту |
| поле часа | Не более одного раза в час |
| поле дня | Не более одного раза в день |
| поле месяца | Не более одного раза в месяц |
| поле дня недели | Не более одного раза в неделю |
Примеры:
* once * * * // runs only once per hour
* * once * * // runs only once per day
* 9-18 once * * // runs only once between 9:00 and 18:59 each day
once в сочетании с диапазонами / списками / шагами
once / once(...) можно комбинировать с любым синтаксисом cron, но правило одно:
В пределах одного цикла после успешного запуска все дальнейшие совпадающие моменты времени игнорируются
Пример 1: диапазон
* 10 once * *
Смысл:
- Каждый день кандидаты — 10:00–10:59
- После первого совпадения за день
- 10:05–10:59 больше не запускаются
Пример 2: список
* 1,3,5 once * *
Смысл:
- Каждый день кандидаты — 1:00, 3:00 и 5:00
- Если уже был запуск в 1:00
- 3:00 и 5:00 будут пропущены
Пример 3: шаг
* */4 once * *
Смысл:
- Каждый день кандидаты — 0:00, 4:00, 8:00, 12:00, 16:00 и 20:00
- После первого запуска за день
- Дальнейшие моменты времени не выполняются
Пример 4: once(...) с указанием кандидатов
* once(9-17) * * *
Смысл:
- Каждый день кандидаты по часам — с 9:00 по 17:00
- Цикл сбрасывается каждый час; в пределах часа первое совпадение останавливает дальнейшие запуски
- Итог: один раз в час между 9:00 и 17:00 каждый день, всего 9 раз
* 9-18 once * *
Смысл:
- Каждый день кандидаты — 9:00–18:59
onceв поле дня фиксирует цикл «раз в день»- После первого совпадения за день до 18:59 больше ничего не выполняется
Примеры @crontab
Обычные
//@crontab * * * * * // runs once per minute
//@crontab * * * * * * // runs once per second (not recommended)
//@crontab 0 */6 * * * // runs on the hour every 6 hours
//@crontab 15 */6 * * * // runs at minute 15 every 6 hours
//@crontab * once * * * // runs at most once per hour
//@crontab * * once * * // runs at most once per day
//@crontab * 10 once * * // runs only once within the 10:00 hour each day (e.g. if it ran at 10:04, it won't run again from 10:05-10:59)
//@crontab * */4 once * * // checks at most once every 4 hours each day (e.g. if it ran at 4:00, it won't run again at 8, 12, 16, 20, 24, etc.)
Продвинутые
//@crontab * 1,3,5 once * * // runs once at 1:00, 3:00, or 5:00 each day (e.g. if it ran at 1:00, it won't run again at 3:00 or 5:00)
//@crontab * 10-23 once * * // runs once between 10:00 and 23:59 each day (e.g. if it ran at 10:04, it won't run again from 10:05-23:59)
//@crontab * once 13 * * // runs once per hour on the 13th of every month
//@crontab * once(9-17) * * * // runs once per hour between 9:00 and 17:00 each day
//@crontab 0,30 once * * * // whichever of minute 0 or 30 is matched first each hour runs; no repeat that hour
//@crontab * 9-18 once * * // runs only once between 9:00 and 18:00 each day
Рекомендации по использованию
Хорошо подходит для once
-
Задачи, которые нужно выполнить только один раз в день/час
-
Проверки статуса, синхронизация и отчётные скрипты
-
Избежание следующих проблем:
- Браузер долго не открывали
- Задержки планирования фоновой страницы
- Повторное выполнение из‑за перезапуска браузера
Не рекомендуется для once
- Задачи, которые должны сработать в точный момент
- Скрипты, время выполнения которых может заметно превысить интервал cron
- Задачи со строгими требованиями к числу выполнений
Проверка cron-выражений
При проверке cron-выражения временно замените once / once(...) на их базовое значение:
once→*once(expr)→expr
Учтите, что тестовые инструменты могут не поддерживать расширенный формат из 6 полей.
Рекомендуемые инструменты:
На странице списка скриптов наведите курсор на столбец статуса выполнения, чтобы увидеть время следующего запланированного запуска.
Журналы
На странице списка скриптов при наведении на столбец статуса выполнения показывается подсказка со статусом;
щелчок открывает содержимое журнала, выведенное через GM_log.

Отладка скрипта
Фоновые скрипты можно отлаживать прямо со страницы редактора, но с ограничениями:
valueсинхронизируется некорректно- меню
registerMenuсрабатывают некорректно

Чтобы отладить реальное окружение выполнения, включите режим разработчика в настройках расширения, затем откройте страницу расширения background.html для отладки.
Ошибки во время выполнения также можно посмотреть в журнале запусков.

Promise
Настоятельно рекомендуется следующий шаблон — он также позволяет менеджеру скриптов отслеживать выполнение.
Если скрипт выполняет любую асинхронную операцию, он должен вернуть Promise.
// ==UserScript==
// @name Background Script
// @namespace wyz
// @version 1.0.0
// @author wyz
// @background
// ==/UserScript==
return new Promise((resolve, reject) => {
if (Math.round((Math.random() * 10) % 2)) {
resolve("ok"); // succeeded
} else {
reject("error"); // failed, with the error reason
}
});
// ==UserScript==
// @name Scheduled script that runs once a day
// @namespace wyz
// @version 1.0.0
// @author wyz
// @crontab * * once * *
// ==/UserScript==
return new Promise((resolve, reject) => {
if (Math.round((Math.random() * 10) % 2)) {
resolve("ok"); // succeeded
} else {
reject("error"); // failed, with the error reason
}
});
// ==UserScript==
// @name Call an API
// @namespace wyz
// @version 1.0.0
// @author wyz
// @crontab * * once * *
// ==/UserScript==
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
url: "https://bbs.tampermonkey.net.cn/",
onload() {
resolve("ok"); // succeeded
},
onerror() {
reject("error"); // failed, with the error reason
},
});
});
Вызывайте resolve / reject только после того, как логика скрипта действительно завершена.
После вызова менеджер считает выполнение скрипта завершённым, и последующие операции GM больше не действуют.
Повтор при ошибке
Фоновые скрипты ScriptCat поддерживают повтор при ошибке.
При сбое скрипт может вызвать reject с CATRetryError, чтобы запустить повтор.
- Минимальный интервал повтора: 5 секунд
- Избегайте конфликта с собственным временем выполнения скрипта, иначе возможно дублирование
// ==UserScript==
// @name Retry example
// @namespace https://bbs.tampermonkey.net.cn/
// @version 0.1.0
// @description try to take over the world!
// @author You
// @crontab * * once * *
// @grant GM_notification
// ==/UserScript==
return new Promise((resolve, reject) => {
GM_notification({
title: "retry",
text: "Retrying in 10 seconds",
});
reject(new CATRetryError("xxx error", 10));
});