دليل المبتدئين لاستخدام واجهات برمجة تطبيقات IndexedDB

@apidog

@apidog

24 أكتوبر 2025

دليل المبتدئين لاستخدام واجهات برمجة تطبيقات IndexedDB

Apidog للمؤسسات

نشر محلي

SSO & RBAC

متوافق مع SOC 2

استكشاف Apidog Enterprise

لقد أصبحت التطبيقات التي تعمل بشكل سلس عند عدم الاتصال بالإنترنت متطلبًا رئيسيًا في تطوير الويب الحديث. تقدم IndexedDB حلاً قويًا للمطورين الذين يتطلعون إلى تخزين وإدارة كميات كبيرة من البيانات مباشرة في المتصفح. تسمح هذه قاعدة بيانات NoSQL الخاصة بالعميل بمعالجة البيانات بكفاءة، مما يجعلها مثالية لتطبيقات الويب التي تحتاج إلى وظائف متصلة بالإنترنت. في هذه المقالة، سنستكشف أساسيات IndexedDB وميزاتها الرئيسية وسنرشدك خلال الخطوات اللازمة لإعدادها واستخدامها في مشاريع الويب الخاصة بك.

ما هي IndexedDB؟

IndexedDB هي قاعدة بيانات NoSQL قوية على جانب العميل تمكن تطبيقات الويب من تخزين وإدارة البيانات الهيكلية مباشرة في المتصفح. إنها توفر حلاً فعالًا للتعامل مع مجموعات بيانات كبيرة محليًا، مما يجعلها مثالية للوظائف المتصلة بالإنترنت والتطبيقات التي تتعامل مع البيانات بكثافة.

تتمثل إحدى المزايا الرئيسية لـ IndexedDB في قدرتها على دعم تطبيقات الويب النشطة دون اتصال بالإنترنت. إنها تسمح للمطورين بتخزين كميات كبيرة من البيانات، واستخدام الفهرسة للاسترجاع السريع، وإدارة المعاملات، والتنقل عبر البيانات باستخدام المؤشرات. تجعل هذه الميزات منها خيارًا ممتازًا للتعامل مع البيانات المعقدة في تطبيقات الويب.

تدعم معظم متصفحات الويب الحديثة، بما في ذلك Chrome وFirefox وSafari وEdge، IndexedDB. ومع ذلك، من المهم التأكد من أن إصدار IndexedDB متوافق مع المتصفح المستهدف لتطبيق الويب الخاص بك.

لبدء استخدام IndexedDB، الخطوة الأولى هي فتح اتصال بقاعدة البيانات، وهو ضروري لإنشائها والتفاعل معها.

💡
عندما تعمل أيضًا مع واجهات برمجة التطبيقات، من المهم أن تأخذ في الاعتبار كيفية أن أدوات مثل Apidog يمكن أن تسهل سير العمل الخاص بك. Apidog توفر منصة موحدة تسهل تصميم واجهات برمجة التطبيقات، واختبارها، وتوثيقها. على عكس الأدوات الأخرى التي تتطلب خطوات منفصلة متعددة لإدارة واجهات برمجة التطبيقات، يجمع Apidog كل شيء في مكان واحد مع ميزات مثل المزامنة في الوقت الحقيقي والتعاون السلس لفرق التطوير.
زر

البدء مع IndexedDB: دليل شامل

IndexedDB هي حل تخزين قوي على جانب العميل لتطبيقات الويب. سيقدِّم لك هذا الدليل كل شيء من الإعداد الأساسي إلى التقنيات المتقدمة والتطبيقات في العالم الحقيقي.

إعداد IndexedDB

إنشاء وفتح قاعدة بيانات

لإنشاء قاعدة بيانات جديدة في IndexedDB، ستستخدم indexedDB.open():

const request = indexedDB.open("MyDatabase", 1);
request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // أنشئ متاجر الكائنات والفهارس هنا
};

تأخذ الطريقة معاملتين: اسم قاعدة البيانات ورقم الإصدار. لفتح قاعدة بيانات موجودة، يمكنك ببساطة استدعاء الطريقة دون تحديد رقم إصدار.

إصدار قاعدة البيانات

تدعم IndexedDB الإصدار للتعامل مع تغييرات المخطط. عند فتح قاعدة بيانات برقم إصدار أعلى من الموجود، يتم تفعيل حدث onupgradeneeded، مما يسمح لك بتحديث مخطط قاعدة البيانات الخاصة بك.

إنشاء متاجر الكائنات والفهارس

متاجر الكائنات هي حاويات للبيانات الخاصة بك في IndexedDB:

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // أنشئ متجر كائنات مع مسار المفتاح
  const objectStore = db.createObjectStore("customers", { keyPath: "id" });
  
  // أنشئ فهرس للاستعلام بشكل فعال
  objectStore.createIndex("name", "name", { unique: false });
};

العمل مع المعاملات

فهم أساسيات المعاملات

تحافظ المعاملات في IndexedDB على سلامة البيانات من خلال تجميع عمليات متعددة في وحدة ذرية واحدة. إنها تضمن أنه تم تطبيق جميع التغييرات أو لم يُطبق أي منها.

إنشاء وإدارة المعاملات

const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");

transaction.oncomplete = (event) => {
  console.log("اكتملت المعاملة بنجاح");
};

transaction.onerror = (event) => {
  console.error("فشلت المعاملة");
};

معالجة الأخطاء والتراجع

إذا فشلت عملية، يمكنك استخدام abort() للتراجع عن المعاملة بالكامل:

try {
  // تنفيذ العمليات
} catch (error) {
  transaction.abort();
  console.error("تم التراجع عن المعاملة:", error);
}

عمليات البيانات في IndexedDB

إضافة البيانات

const customerData = { id: "00001", name: "جون دو", email: "john@example.com" };
const request = objectStore.add(customerData);

request.onsuccess = (event) => {
  console.log("تمت إضافة البيانات بنجاح");
};

استرجاع البيانات

استرجاع البيانات الأساسية بناءً على المفتاح:

const request = objectStore.get("00001");
request.onsuccess = (event) => {
  console.log("بيانات العميل:", request.result);
};

التصفية باستخدام الفهارس

const index = objectStore.index("name");
const request = index.get("جون دو");

request.onsuccess = (event) => {
  console.log("تم العثور عليه بالاسم:", request.result);
};

طرق الاستعلام المتقدمة

لتنفيذ استعلامات معقدة، تقدم IndexedDB استعلامات النطاق والاستعلامات المركبة باستخدام طرق مثل openCursor() وIDBKeyRange:

const range = IDBKeyRange.bound("A", "F"); // الأسماء التي تبدأ بـ A حتى F
const request = index.openCursor(range);

تحديث السجلات

const updateData = { id: "00001", name: "جون سميث", email: "john@example.com" };
const request = objectStore.put(updateData);

حذف السجلات

const request = objectStore.delete("00001");
request.onsuccess = (event) => {
  console.log("تم حذف السجل");
};

العمل مع المؤشرات

فهم وظائف المؤشرات

تسمح لك المؤشرات بالتكرار بكفاءة عبر السجلات في متجر الكائنات أو الفهرس، مما يوفر وسيلة للتنقل والتلاعب بالبيانات.

التنقل عبر السجلات

const request = objectStore.openCursor();
request.onsuccess = (event) => {
  const cursor = event.target.result;
  if (cursor) {
    console.log("المفتاح:", cursor.key, "القيمة:", cursor.value);
    cursor.continue(); // الانتقال إلى السجل التالي
  } else {
    console.log("لا توجد سجلات أخرى");
  }
};

تعديل البيانات باستخدام المؤشرات

const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.openCursor();

request.onsuccess = (event) => {
  const cursor = event.target.result;
  if (cursor) {
    if (cursor.value.status === "غير نشط") {
      const updateData = cursor.value;
      updateData.status = "نشط";
      cursor.update(updateData);
    }
    cursor.continue();
  }
};

إدارة المخطط والترقيات

ترقية مخطط قاعدة البيانات

عندما تتطور تطبيقك، قد تحتاج إلى تعديل مخطط قاعدة البيانات:

const request = indexedDB.open("MyDatabase", 2); // زيادة رقم الإصدار

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  
  // التحقق مما إذا كان متجر الكائنات موجودًا
  if (!db.objectStoreNames.contains("newStore")) {
    db.createObjectStore("newStore", { keyPath: "id" });
  }
};

ترحيل البيانات أثناء الترقيات

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const oldVersion = event.oldVersion;
  
  if (oldVersion < 1) {
    // إعداد الإصدار الأول
  }
  
  if (oldVersion < 2) {
    // ترحيل البيانات إلى المخطط الجديد
    const transaction = event.target.transaction;
    const oldStore = transaction.objectStore("oldStore");
    const newStore = db.createObjectStore("newStore", { keyPath: "id" });
    
    oldStore.openCursor().onsuccess = (event) => {
      const cursor = event.target.result;
      if (cursor) {
        newStore.add(cursor.value);
        cursor.continue();
      }
    };
  }
};

تحسين الأداء

عمليات الشحن الجماعي الفعالة

لتحسين الأداء، استخدم عمليات الشحن الجماعي عند التعامل مع سجلات متعددة:

const transaction = db.transaction(["customers"], "readwrite");
const store = transaction.objectStore("customers");

// إضافة سجلات متعددة في معاملة واحدة
customerList.forEach(customer => {
  store.add(customer);
});

الاستفادة من الفهارس لاستعلامات أسرع

أنشئ فهارس على الخصائص التي يتم استعلامها بشكل متكرر لضمان استرجاع بيانات أسرع:

objectStore.createIndex("email", "email", { unique: true });
objectStore.createIndex("lastLogin", "lastLogin", { unique: false });

أفضل ممارسات إدارة الاتصال

افتح الاتصالات فقط عند الضرورة وأغلقها عند الانتهاء:

let db;

function openDB() {
  const request = indexedDB.open("MyDatabase", 1);
  request.onsuccess = (event) => {
    db = event.target.result;
  };
  return request;
}

// عندما تكون قد انتهيت من قاعدة البيانات
function closeDB() {
  if (db) {
    db.close();
    db = null;
  }
}

مثال من العالم الحقيقي: مدير المهام مع دعم دون اتصال

إعداد قاعدة البيانات

const request = indexedDB.open("TaskManagerDB", 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const taskStore = db.createObjectStore("tasks", { keyPath: "id", autoIncrement: true });
  
  // أنشئ فهارس لاستعلام المواد
  taskStore.createIndex("status", "status", { unique: false });
  taskStore.createIndex("dueDate", "dueDate", { unique: false });
};

إضافة المهام

function addTask(taskData) {
  const transaction = db.transaction(["tasks"], "readwrite");
  const taskStore = transaction.objectStore("tasks");
  
  return new Promise((resolve, reject) => {
    const request = taskStore.add({
      title: taskData.title,
      description: taskData.description,
      status: "معلق",
      dueDate: taskData.dueDate,
      createdAt: new Date()
    });
    
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
}

استرجاع وعرض المهام

function getAllTasks() {
  const transaction = db.transaction(["tasks"], "readonly");
  const taskStore = transaction.objectStore("tasks");
  
  return new Promise((resolve, reject) => {
    const request = taskStore.openCursor();
    const tasks = [];
    
    request.onsuccess = (event) => {
      const cursor = event.target.result;
      if (cursor) {
        tasks.push(cursor.value);
        cursor.continue();
      } else {
        resolve(tasks);
      }
    };
    
    request.onerror = () => reject(request.error);
  });
}

تحديث وحذف المهام

function updateTaskStatus(id, newStatus) {
  const transaction = db.transaction(["tasks"], "readwrite");
  const taskStore = transaction.objectStore("tasks");
  
  return new Promise((resolve, reject) => {
    const getRequest = taskStore.get(id);
    
    getRequest.onsuccess = () => {
      const task = getRequest.result;
      task.status = newStatus;
      task.updatedAt = new Date();
      
      const updateRequest = taskStore.put(task);
      updateRequest.onsuccess = () => resolve(true);
      updateRequest.onerror = () => reject(updateRequest.error);
    };
    
    getRequest.onerror = () => reject(getRequest.error);
  });
}

المزامنة مع الخادم

function syncWithServer() {
  if (!navigator.onLine) {
    return Promise.reject(new Error("لا يوجد اتصال بالإنترنت"));
  }
  
  return getAllTasks()
    .then(tasks => {
      // تصفية المهام التي تحتاج إلى المزامنة
      const unsynced = tasks.filter(task => !task.synced);
      
      // الإرسال إلى الخادم باستخدام واجهة برمجة التطبيقات fetch
      return fetch('https://api.example.com/tasks/sync', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(unsynced)
      });
    })
    .then(response => response.json())
    .then(result => {
      // وسم المهام على أنها متزامنة
      const transaction = db.transaction(["tasks"], "readwrite");
      const taskStore = transaction.objectStore("tasks");
      
      result.syncedIds.forEach(id => {
        const request = taskStore.get(id);
        request.onsuccess = () => {
          const task = request.result;
          task.synced = true;
          taskStore.put(task);
        };
      });
      
      return result;
    });
}

// الاستماع لفعاليات الاتصال بالإنترنت لمزامنة تلقائية
window.addEventListener('online', syncWithServer);

دمج Apidog لإدارة واجهات برمجة التطبيقات مع IndexedDB

عند بناء التطبيقات باستخدام IndexedDB للتخزين على جانب العميل، ستحتاج غالبًا إلى التفاعل مع واجهات برمجة التطبيقات الخلفية لمزامنة البيانات. يوفر Apidog حلاً سلسًا لإدارة هذه التفاعلات مع واجهات برمجة التطبيقات.

لماذا يعزز Apidog تطوير IndexedDB

بينما تطور تطبيقات قادرة على العمل دون اتصال باستخدام IndexedDB، يقدم Apidog عدة مزايا:

المزامنة في الوقت الحقيقي: يضمن Apidog أن نقاط نهاية واجهة برمجة التطبيقات الخاصة بك المستخدمة لمزامنة البيانات تم تكوينها واختبارها بشكل صحيح، الأمر الذي يقضي على مشكلات الدمج عندما يصبح تطبيقك متصلاً بالإنترنت.

ردود واجهة برمجة التطبيقات الوهمية: عند تطوير وظائف عدم الاتصال، تتيح محركات المحاكاة الذكية في Apidog لك محاكاة ردود واجهة برمجة التطبيقات لاختبار منطق المزامنة في IndexedDB دون خادم حي.

تصميم واجهة برمجة التطبيقات التعاونية: عندما يعمل فريقك في الوقت نفسه على تخزين الواجهة الأمامية وواجهات برمجة التطبيقات الخلفية، يسهل Apidog التعاون الفوري على مواصفات واجهات برمجة التطبيقات.

من خلال دمج Apidog في سير العمل الخاص بك في التطوير، يمكنك إنشاء جسر سلس بين التخزين على جانب العميل ومعالجة جانب الخادم، مما يجعل تطبيقك أكثر قوة وأسهل في الصيانة.

زر

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات