פיתוח טופס העלאת קבצים מותאם אישית עבור 1C-Bitrix
נתקלנו במצבים: לקוח מצרף מפרט טכני, תמונות ליקויי מוצר או שרטוטים, והרכיב הסטנדרטי bitrix:main.feedback אינו מספק את המענה. אין תצוגה מקדימה, אין גרירה ושחרור, אין אימות סוג קבצים בצד הלקוח, אין העלאה בחלקים עבור קבצים גדולים. התוצאה היא פניות אבודות וחוויית משתמש פגומה. טופס העלאת קבצים מותאם אישית עבור 1C-Bitrix פותר בעיות אלו. אנו מיישמים פתרון סוהר המשולב עם b_file ו-CRM שמספק חיסכון משמעותי בעלויות באמצעות אוטומציה.
בעיות שאנו פותרים
- פסקי זמן עם קבצים גדולים: קובץ בודד של 100 MB באמצעות POST סטנדרטי עלול לגרום לפסק זמן בחיבורים איטיים. אנו משתמשים בהעלאה בחלקים — פיצול הקובץ לחלקים של 5 MB, העלאה רציפה עם חיווי התקדמות. חיסכון בזמן של עד 70%, הפחתת אובדן פניות עד 35%. העלאה בחלקים אמינה פי שלושה מ-POST סטנדרטי בחיבורים לא יציבים.
-
חוסר אימות בצד הלקוח: משתמשים חסרי ניסיון מנסים להעלות
.exeאו.dll. בשרת אנו בודקים MIME באמצעות finfo ודוחים סוגים אסורים. בצד הלקוח, אימות לפי סיומת. זה מפחית עומס על השרת ומונע אירועי אבטחה. - חוסר יכולת לצרף מספר קבצים: שדה קובץ בודד אינו מתאים למפרט טכני + שרטוטים + תמונות. אנו מיישמים העלאה מרובה עם מגבלה של 10 קבצים לכל סשן, המכסה 95% מתרחישי העסק.
-
שימוש מופרז בזיכרון: POST סטנדרטי טוען את כל הקובץ לזיכרון PHP. הגישה שלנו מבוססת AJAX נמנעת מכך — קבצים מועלים בנפרד, ו-PHP מעבד רק
tmp_name.
כיצד פועלת העלאה בחלקים
עבור קבצים מעל 50 MB, בקשת POST בודדת אינה אמינה. ה-ChunkedUploader שלנו מפצל את הקובץ לחלקים, מעלה אותם ברצף ומרכיב אותם מחדש בשרת. תוצאה: העלאת קבצים עד 2 GB עם פס התקדמות, ללא פסקי זמן. השוואה: העלאה סטנדרטית של 200 MB עלולה להיכשל עם שגיאה 413 לאחר 30 שניות; עם העלאה בחלקים, שידור יציב עם אפשרות חידוש במקרה של כשל.
| מאפיין | העלאה סטנדרטית | העלאה בחלקים |
|---|---|---|
| גודל קובץ מקסימלי | ~20 MB (מגבלת PHP) | עד 2 GB |
| פס התקדמות | לא | כן, לכל חלק |
| חידוש לאחר הפרעה | לא | כן, מהחלק האחרון |
| עומס זיכרון | גבוה | נמוך |
דוגמת יישום של ChunkedUploader
class ChunkedUploader { constructor(file, options = {}) { this.file = file; this.chunkSize = options.chunkSize || 5 * 1024 * 1024; // 5 MB this.onProgress = options.onProgress || (() => {}); this.uploadId = null; } async upload() { // Инициализируем multipart upload const initRes = await fetch('/local/api/upload-init.php', { method: 'POST', body: JSON.stringify({ filename : this.file.name, size : this.file.size, mime : this.file.type, sessid : BX.bitrix_sessid(), }), headers: { 'Content-Type': 'application/json' }, }); const { upload_id } = await initRes.json(); this.uploadId = upload_id; const totalChunks = Math.ceil(this.file.size / this.chunkSize); for (let i = 0; i < totalChunks; i++) { const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, this.file.size); const chunk = this.file.slice(start, end); const formData = new FormData(); formData.append('upload_id', this.uploadId); formData.append('chunk_index', i); formData.append('total_chunks', totalChunks); formData.append('chunk', chunk); await fetch('/local/api/upload-chunk.php', { method: 'POST', body: formData, }); this.onProgress(Math.round((i + 1) / totalChunks * 100)); } // Финализируем const finalRes = await fetch('/local/api/upload-finalize.php', { method: 'POST', body: JSON.stringify({ upload_id: this.uploadId }), headers: { 'Content-Type': 'application/json' }, }); return finalRes.json(); // { file_id, name, size, ... } } } מדוע אימות סוג MIME הוא קריטי
העלאת קבצי הפעלה עלולה להוביל לחדירות לשרת. אנו בודקים את סוג MIME באמצעות ספריית finfo, ולא רק את הסיומת. זה מגן מפני התקפות סיומת כפולה (לדוגמה, class ChunkedUploader { constructor(file, options = {}) { this.file = file; this.chunkSize = options.chunkSize || 5 * 1024 * 1024; // 5 MB this.onProgress = options.onProgress || (() => {}); this.uploadId = null; } async upload() { // Инициализируем multipart upload const initRes = await fetch('/local/api/upload-init.php', { method: 'POST', body: JSON.stringify({ filename : this.file.name, size : this.file.size, mime : this.file.type, sessid : BX.bitrix_sessid(), }), headers: { 'Content-Type': 'application/json' }, }); const { upload_id } = await initRes.json(); this.uploadId = upload_id; const totalChunks = Math.ceil(this.file.size / this.chunkSize); for (let i = 0; i < totalChunks; i++) { const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, this.file.size); const chunk = this.file.slice(start, end); const formData = new FormData(); formData.append('upload_id', this.uploadId); formData.append('chunk_index', i); formData.append('total_chunks', totalChunks); formData.append('chunk', chunk); await fetch('/local/api/upload-chunk.php', { method: 'POST', body: formData, }); this.onProgress(Math.round((i + 1) / totalChunks * 100)); } // Финализируем const finalRes = await fetch('/local/api/upload-finalize.php', { method: 'POST', body: JSON.stringify({ upload_id: this.uploadId }), headers: { 'Content-Type': 'application/json' }, }); return finalRes.json(); // { file_id, name, size, ... } } } ). שילוב עם ClamAV מספק סריקת אנטי-וירוס על כל קובץ מבלי להוסיף יותר מ-1.5 שניות לזמן העיבוד. זה מפחית עלויות תפעוליות עד 40% באמצעות בדיקות אוטומטיות.
| שיטת אימות | אמינות | מהירות |
|---|---|---|
| סיומת בלבד | נמוכה | גבוהה |
| MIME באמצעות finfo | גבוהה | בינונית |
| MIME + ClamAV | מקסימלית | קצת נמוכה יותר |
כיצד פועלת ארכיטקטורת ההעלאה
עבור טפסים הנושאים קבצים אנו משתמשים בתהליך דו-שלבי:
- הקובץ מועלה באמצעות בקשת AJAX נפרדת לפני שליחת הטופס. מוחזר
file_idזמני. - בשליחת הטופס הסופית, מועברים רק הפניות
file_id, לא הקבצים בפועל.
זה מונע פסקי זמן עם קבצים גדולים ומאפשר חיווי התקדמות עצמאי לכל קובץ. לפי תיעוד 1C-Bitrix, CFile::SaveFile() מחזיר את מזהה הקובץ שהועלה ושומר אותו בטבלת b_file.
מה כלול בפיתוח טופס ההעלאה
- רכיב
local:file.uploadעם אזור גרירה ושחרור ותצוגה מקדימה של תמונות - מטפל העלאה בצד השרת: אימות סוג באמצעות finfo, CSRF, הגבלת קצב
- שמירה באמצעות CFile::SaveFile() לטבלת
b_file - העלאה בחלקים עבור קבצים > 10 MB (אופציונלי)
- שדה משתמש
UF_ATTACHMENTS(FILE, MULTIPLE) ב-CRM - צירוף קבצים שהועלו לליד שנוצר
- הודעה למנהל עם קישורים ישירים לקבצים המצורפים
- תיעוד תפעולי, העברת גישה, הגדרת הרשאות
תהליך ההערכה והעבודה
- ניתוח: הבנת התרחיש — אילו קבצים, היכן הם מצורפים, האם נדרשת אינטגרציה עם CRM.
- עיצוב: בחירת שיטת אחסון (שדה משתמש, פעילות), הגדרת מגבלות.
- יישום: כתיבת רכיב, מטפלי שרת, נקודות קצה API.
- בדיקות: אימות העלאה של סוגים שונים, גדלים, אבטחה.
- פריסה והדרכה: פריסה לסביבת ייצור, הדרכת מנהלים.
לוחות זמנים (משוערים)
טופס בסיסי עם צירוף קובץ בודד: 3–5 ימים. גרסה מלאה עם גרירה ושחרור, תצוגה מקדימה, העלאה בחלקים ואינטגרציה עם CRM: 2–3 שבועות. העלות מחושבת באופן אישי — נבחן את הפרויקט שלך לאחר שיחת ייעוץ קצרה. בקשו ייעוץ ונכין הצעת מחיר המותאמת לתקציב שלך.
למה לבחור בנו?
- 10+ שנות ניסיון עם 1C-Bitrix ו-Bitrix24.
- 50+ פרויקטים שהושלמו הכוללים טפסים מותאמים אישית ואינטגרציות.
- כל מודול עובר בדיקת קוד ובדיקות עומס.
- מומחים מוסמכים ב-Bitrix וב-Bitrix24.
צרו קשר לייעוץ ללא התחייבות. הזמינו הערכת עלות אישית.







