Vue.js ו-1C-Bitrix: הגדרת תקשורת באמצעות REST API
לקוחות מגיעים לעיתים קרובות עם SPA מוכן ב-Vue.js שאינו יכול לקבל נתונים מ-1C-Bitrix. הסיבה היא בחירה שגויה של מנגנון ה-API. אנו מגדירים את האינטגרציה כך שה-SPA עובד כחלק מהאתר: עם הרשאות, מטמון ואבטחה. לדוגמה, טעות אופיינית היא ניסיון להשתמש ב-REST API המובנה לבחירת קטלוג כבד, מה שמוביל לחריגה ממגבלת הבקשות ולשגיאות 429. במאמר ננתח שלוש גישות ונראה איזו מהן לבחור למשימה שלכם.
Bitrix מספקת מספר מנגנונים לעבודה עם נתונים מ-Vue: REST API מובנה (/bitrix/rest/), שיטות ORM דרך בקרי AJAX (Bitrix\Main\Engine\Controller), ובקשות AJAX ישירות למטפלי רכיבים. בחירת המנגנון משפיעה על ביצועים, אבטחה ונפח קוד. ננתח כל גישה עם דוגמאות מעשיות והמלצות.
REST API מובנה של Bitrix
זמין בכתובת /rest/ עבור Bitrix24 בענן ודורש הגדרה עבור הגרסה המקומית (הפעלת מודול REST API). שיטות — sale.basket.getlist, catalog.product.list, crm.deal.list ועוד. הרשאה דרך OAuth 2.0 או דרך webhooks (כתובת webhook עם טוקן). עבור API ציבורי באתר (לא Bitrix24) — webhooks עם הרשאות מוגבלות.
תיעוד רשמי של 1C-Bitrix ממליץ להשתמש ב-webhooks לתרחישים פשוטים, אך מזהיר מפני מגבלות בקשות (50 בשנייה לענן). עבור גרסה מקומית אין מגבלות, אך מהירות התגובה עשויה להיות נמוכה עם בחירות מורכבות.
const BX_WEBHOOK = window.BX_STATE.webhook; // передаётся из PHP
async function getProducts(filter) {
const res = await fetch(`${BX_WEBHOOK}catalog.product.list`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
filter,
select: ['ID', 'NAME', 'PRICE']
}),
});
return res.json();
}מגבלות של REST המובנה: מגבלות בקשות, לא כל הישויות זמינות, לא ניתן להריץ שאילתות SQL שרירותיות.
בקרים מותאמים אישית דרך Engine\Controller
לפרויקטים על Bitrix מקומית, השיטה העיקרית היא בקרים מותאמים אישית דרך Engine\Controller. הבקר חי במודול מותאם אישית. בניגוד ל-REST API, מקבלים שליטה מלאה על נתונים, תמיכה במטמון מתויג ויכולת לשלב בקשות.
// local/modules/project.api/lib/controller/product.php
namespace Project\Api\Controller;
use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Engine\ActionFilter;
class Product extends Controller
{
public function configureActions(): array
{
return [
'list' => [
'prefilters' => [
new ActionFilter\Authentication()
],
],
];
}
public function listAction(int $categoryId, int $page = 1): array
{
$pageSize = 20;
$res = \CIBlockElement::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'SECTION_ID' => $categoryId, 'ACTIVE' => 'Y'],
false,
['nPageSize' => $pageSize, 'iNumPage' => $page],
['ID', 'NAME', 'DETAIL_PICTURE', 'PROPERTY_PRICE']
);
$items = [];
while ($item = $res->GetNext()) {
$items[] = $item;
}
return ['items' => $items, 'page' => $page];
}
}כתובת הבקר: const BX_WEBHOOK = window.BX_STATE.webhook; // передаётся из PHP async function getProducts(filter) { const res = await fetch(`${BX_WEBHOOK}catalog.product.list`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ filter, select: ['ID', 'NAME', 'PRICE'] }), }); return res.json(); } . מוסיף אוטומטית הגנת CSRF כאשר // local/modules/project.api/lib/controller/product.php namespace Project\Api\Controller; use Bitrix\Main\Engine\Controller; use Bitrix\Main\Engine\ActionFilter; class Product extends Controller { public function configureActions(): array { return [ 'list' => [ 'prefilters' => [new ActionFilter\Authentication()], ], ]; } public function listAction(int $categoryId, int $page = 1): array { $pageSize = 20; $res = \CIBlockElement::GetList( ['SORT' => 'ASC'], ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'SECTION_ID' => $categoryId, 'ACTIVE' => 'Y'], false, ['nPageSize' => $pageSize, 'iNumPage' => $page], ['ID', 'NAME', 'DETAIL_PICTURE', 'PROPERTY_PRICE'] ); $items = []; while ($item = $res->GetNext()) { $items[] = $item; } return ['items' => $items, 'page' => $page]; } } .
Axios ב-Vue: שירות API אחיד
// services/api.js
import axios from 'axios';
const api = axios.create({
baseURL: '/bitrix/services/main/ajax.php',
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
});
// Автоматически добавляем CSRF-токен
api.interceptors.request.use(config => {
if (config.method === 'post') {
config.data = {
...config.data,
sessid: window.BX.bitrix_sessid()
};
}
return config;
});
// Обработка 401 — редирект на авторизацию
api.interceptors.response.use(
res => res.data,
err => {
if (err.response?.status === 401) {
window.location.href = '/auth/?backurl=' + encodeURIComponent(location.pathname);
}
return Promise.reject(err);
}
);
export const getProducts = (categoryId, page) => api.post('', {
action: 'project:api.product.list',
categoryId,
page
});
כל רכיבי Vue משתמשים בפונקציות מ-/bitrix/services/main/ajax.php?action=project:api.product.list — הם לא מבצעים fetch ישירות. שינוי כתובת URL או מנגנון הרשאה — בקובץ אחד.
Composable לנתונים
// composables/useProducts.js
export function useProducts(categoryId) {
const items = ref([]);
const loading = ref(false);
const error = ref(null);
const page = ref(1);
async function load() {
loading.value = true;
error.value = null;
try {
const data = await getProducts(categoryId.value, page.value);
items.value = page.value === 1 ? data.items : [...items.value, ...data.items];
} catch (e) {
error.value = e.message;
} finally {
loading.value = false;
}
}
watch(categoryId, () => {
page.value = 1;
load();
}, { immediate: true });
return {
items,
loading,
error,
page,
loadMore: () => {
page.value++;
load();
}
};
}Composable עוטף את לוגיקת הטעינה; הרכיב עובד רק עם נתונים ריאקטיביים.
CORS ומדיניות אבטחה
עבור SPA בתת-דומיין נפרד (POST) ל-API ב-(// services/api.js import axios from 'axios'; const api = axios.create({ baseURL: '/bitrix/services/main/ajax.php', headers: { 'X-Requested-With': 'XMLHttpRequest' }, }); // Автоматически добавляем CSRF-токен api.interceptors.request.use(config => { if (config.method === 'post') { config.data = { ...config.data, sessid: window.BX.bitrix_sessid() }; } return config; }); // Обработка 401 — редирект на авторизацию api.interceptors.response.use( res => res.data, err => { if (err.response?.status === 401) { window.location.href = '/auth/?backurl=' + encodeURIComponent(location.pathname); } return Promise.reject(err); } ); export const getProducts = (categoryId, page) => api.post('', { action: 'project:api.product.list', categoryId, page }); ), נדרשת הגדרת CORS ב-PHP. ללא כותרות מתאימות, הדפדפן חוסם בקשות. בנוסף, יש להעביר עוגיית סשן עם services/api.js ב-axios.
// в начале контроллера или в событии OnPageStart
header('Access-Control-Allow-Origin: https://app.example.com');
header('Access-Control-Allow-Credentials: true');עוגיית הסשן של Bitrix נשלחת עם // composables/useProducts.js export function useProducts(categoryId) { const items = ref([]); const loading = ref(false); const error = ref(null); const page = ref(1); async function load() { loading.value = true; error.value = null; try { const data = await getProducts(categoryId.value, page.value); items.value = page.value === 1 ? data.items : [...items.value, ...data.items]; } catch (e) { error.value = e.message; } finally { loading.value = false; } } watch(categoryId, () => { page.value = 1; load(); }, { immediate: true }); return { items, loading, error, page, loadMore: () => { page.value++; load(); } }; } — סשן ההרשאה עובד בין דומיינים.
איך לבחור בין REST API לבקר מותאם אישית?
| קריטריון | REST API | בקר מותאם אישית |
|---|---|---|
| מהירות פיתוח | גבוהה (שיטות מוכנות) | בינונית (צריך לכתוב קוד) |
| גמישות | נמוכה (רק שיטות זמינות) | גבוהה (כל לוגיקה) |
| מגבלות בקשות | 50/שנייה (ענן) | אין מגבלות |
| אבטחה | OAuth / webhook | CSRF + סשן |
| מתאים ל | SPA פשוט, Bitrix24 | קטלוגים מורכבים, עגלות |
בקר מותאם אישית מנצח בסקלביליות: הוא מהיר פי 2-3 מ-REST API לבחירות גדולות של בלוקי מידע בזכות שאילתות SQL ישירות דרך ORM.
שגיאות אופייניות באינטגרציה של Vue.js עם Bitrix
| שגיאה | תוצאה | פתרון |
|---|---|---|
| שימוש ב-REST API לקטלוגים גדולים | חריגה ממגבלה, שגיאות 429 | מעבר לבקרים מותאמים אישית |
| חוסר בטוקן CSRF בבקשות POST | שגיאה 403, חסימת בקשות | הוספת sessid לנתוני הבקשה |
| הגדרת CORS שגויה | חסימת דפדפן, אין נתונים | הגדרת כותרות ואישורים מתאימים |
| בקשות fetch ישירות מרכיבים | קושי בניפוי באגים והחלפת API | שימוש בשירות API אחיד |
למה להשתמש בבקרים מותאמים אישית?
הם נותנים שליטה מלאה על נתונים. לדוגמה, ניתן לשלב בקשות למספר בלוקי מידע לשיטה אחת, להחיל מטמון מתויג או להוסיף לוגיקה עסקית. REST API המובנה אינו מאפשר זאת. בעבודה עם בקרים מותאמים אישית, ניתן להשתמש בכל התכונות של Bitrix ORM, כולל פילטרים, מיון ופאג'ינציה.
מה כלול בעבודה
- קוד מקור של בקרים, שירותים וקוח API.
- תיעוד מלא לכל השיטות.
- הוראות התקנה לשרת שלכם.
- אחריות ל-30 יום על שינויים.
- שבועיים של תמיכה לאחר מסירת הפרויקט.
תהליך העבודה
- ניתוח — אנו לומדים את ארכיטקטורת האתר שלכם, דרישות SPA, בוחרים את המנגנון האופטימלי.
- עיצוב — עיצוב API, סכמות נתונים, הגנה.
- פיתוח — כתיבת בקרים, הגדרת CORS, יצירת composables.
- בדיקות — בדיקת עומס, אבטחה, מטמון.
- התקנה ותיעוד — פרסום API, מתן הוראות.
לוחות זמנים ועלות
הגדרה בסיסית של שיטת API אחת אורכת 2 עד 3 ימים; העלות מחושבת באופן אישי לאחר ניתוח הפרויקט שלכם. אינטגרציה מלאה של SPA עם קטלוג, עגלה והרשאות אורכת 1 עד 2 שבועות; העלות המדויקת נקבעת בשלב העיצוב.
הצוות שלנו מורכב ממומחים מוסמכים עם ניסיון בעבודה עם 1C-Bitrix ויותר מ-50 פרויקטים מוצלחים ב-Vue.js. אנו מבטיחים יציבות ואבטחה של ה-API. צרו קשר לניתוח מקדים — נבחר את שיטת האינטגרציה האופטימלית. בקשו ייעוץ לפרויקט שלכם, ונציע פתרון.

