كيفية استخدام سكربتات Pre-Request و Post-Response في Apidog

تعلّم كيفية استخدام البرامج النصية قبل الطلب وبعد الاستجابة في Apidog: وقّع الطلبات باستخدام HMAC، عيّن متغيرات ديناميكية، شغّل التأكيدات، وأعد استخدام المنطق مع البرامج النصية العامة.

INEZA Felin-Michel

INEZA Felin-Michel

16 يوليو 2026

كيفية استخدام سكربتات Pre-Request و Post-Response في Apidog

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

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

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

زر

ما تفعله السكريبتات قبل وبعد المعالجة فعليًا

يشغل Apidog السكريبتات في مرحلتين، ويسميهما بوضوح.

تعمل المعالجات المسبقة (Pre Processors) قبل إرسال الطلب إلى الخادم. هذا هو المكان الذي تُحضّر فيه الأشياء: توليد طابع زمني، حساب توقيع، تعيين معرف طلب عشوائي، أو قراءة متغير وتشكيله في رأس (header). الاستجابة لا توجد بعد في هذه النقطة، لذا فإن أي شيء يتفحص استجابة محظور هنا.

تعمل المعالجات اللاحقة (Post Processors) بعد استقبال الاستجابة. هذا هو المكان الذي تتحقق فيه مما عاد باستخدام التأكيدات، وحيث تسحب القيم من النص الأساسي لإعادة استخدامها لاحقًا. استخرج رمزًا مميزًا للمصادقة، احصل على معرف مورد تم إنشاؤه حديثًا، تحقق من رمز الحالة، احفظ مؤشرًا للترقيم.

يتبع قاعدتان من هذا التقسيم. أولاً، pm.response (مع code، status، headers، responseTime، responseSize، text()، و json() الخاص بها) يعمل فقط في المعالجات اللاحقة. لا توجد استجابة للقراءة قبل الإرسال، لذا فإن استدعاءها في معالج مسبق لن يساعدك. ثانيًا، المتغيرات هي كيف تتحدث المرحلتان مع بعضهما البعض. يقوم المعالج المسبق بتعيين قيمة، ويستخدمها الطلب، ويمكن للمعالج اللاحق قراءتها أو الكتابة فوقها.

إذا كنت قادمًا من Postman، لاحظ تغيير التسمية مقدمًا. علامات تبويب Apidog هي المعالجات المسبقة (Pre Processors) والمعالجات اللاحقة (Post Processors)، وليست "سكريبت ما قبل الطلب (Pre-request Script)" و"الاختبارات (Tests)". يتطابق السلوك بشكل وثيق، ولكن الأسماء على الشاشة مختلفة.

الإعداد: افتح طلبًا واعثر على علامات التبويب

قم بتنزيل Apidog للمتابعة. إنه مجاني ويعمل على macOS وWindows وLinux، لذا احصل عليه من صفحة تنزيل Apidog إذا لم يكن لديك بعد.

افتح طلب واجهة برمجة التطبيقات (API) الذي تريد برمجته داخل Apidog. تحتوي كل نقطة نهاية على علامة تبويب المعالجات المسبقة (Pre Processors) وعلامة تبويب المعالجات اللاحقة (Post Processors) جنبًا إلى جنب مع علامات تبويب Params وHeaders وBody المعتادة. لإضافة منطق إلى أي من المرحلتين، افتح علامة التبويب وحدد إضافة سكريبت مخصص (add a Custom Script). يفتح هذا محرر أكواد حيث تكتب JavaScript عاديًا مقابل الكائن pm.

قبل كتابة أي شيء، من المفيد معرفة مكان وجود القيم. يحل Apidog المتغيرات بهذا الترتيب الأولوية:

المتغيرات المحلية (Local Variables) > متغيرات البيئة (Environment Variables) > المتغيرات العامة المشتركة داخل المشروع (Global Variables Shared within Project) > المتغيرات العامة المشتركة داخل الفريق (Global Variables Shared within Team).

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

مثال على المعالج المسبق: توقيع طلب باستخدام HMAC

لنفترض أنك تستدعي نقطة نهاية دفعات تقوم بمصادقة كل طلب باستخدام توقيع HMAC-SHA256. هذا هو نفس النمط الذي يستخدمه العديد من المزودين للتحقق من الـ webhook، وتصف وثائق Stripe للتوقيع ذلك جيدًا: يتوقع الخادم طابعًا زمنيًا وتوقيعًا محسوبًا على هذا الطابع الزمني بالإضافة إلى نص الطلب، مع مفتاح API السري الخاص بك. تحتاج إلى بناء كليهما حديثًا في كل إرسال.

يشحن Apidog مكتبة crypto-js كجزء مدمج، لذلك لا تحتاج إلى تثبيت أي شيء. افتح علامة تبويب المعالجات المسبقة (Pre Processors)، حدد إضافة سكريبت مخصص (add a Custom Script)، واكتب هذا:

// المعالج المسبق: توقيع الطلب قبل إرساله
const CryptoJS = require('crypto-js');

// الطابع الزمني الحالي لـ Unix بالثواني
const timestamp = Math.floor(Date.now() / 1000).toString();

// قراءة المفتاح السري من متغير بيئة
const secret = pm.environment.get('payments_api_secret');

// بناء السلسلة المراد توقيعها: الطابع الزمني + سطر جديد + نص الطلب الخام
const body = pm.request.body ? pm.request.body.toString() : '';
const payload = timestamp + '\n' + body;

// حساب توقيع HMAC-SHA256، بترميز سداسي عشري
const signature = CryptoJS.HmacSHA256(payload, secret).toString(CryptoJS.enc.Hex);

// تخزين كلا القيمتين كمتغيرات بيئة لاستخدامها من قبل الطلب
pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', signature);

pm.console.log('تم توقيع الطلب في ' + timestamp);

يحسب هذا السكريبت التوقيع ويحفظ كلاً من الطابع الزمني والتوقيع في متغيرات البيئة. الآن قم بتوصيلها بالطلب. في علامة تبويب الرؤوس (Headers)، قم بالإشارة إلى القيم المخزنة باستخدام صيغة {{variableName}}:

X-Timestamp: {{x_timestamp}}
X-Signature: {{x_signature}}

عندما ترسل، يشغل Apidog المعالج المسبق أولاً، ويحدد المتغيرين، ثم يستبدلهما في الرؤوس. يتلقى الخادم توقيعًا صالحًا وقت الإرسال، في كل مرة، دون خطوة يدوية. لاحظ أن استدعاء require('crypto-js') يجلب الوحدة بأكملها. أنت تستورد المكتبة بأكملها، وليس وحدة فرعية، لذلك يعمل require('crypto-js') ولا يعمل require('crypto-js/sha256').

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

مثال على المعالج اللاحق: استخراج رمز مميز والتأكيد

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

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": { "id": 4812, "email": "dana@example.com" },
  "expires_in": 3600
}

افتح علامة تبويب المعالجات اللاحقة (Post Processors)، حدد إضافة سكريبت مخصص (add a Custom Script)، واسحب الرمز المميز من النص الأساسي، وحفظه للطلبات اللاحقة:

// المعالج اللاحق: التحقق من الاستجابة، ثم استخراج الرمز المميز
pm.test('الحالة هي 200', function () {
  pm.response.to.have.status(200);
});

const jsonData = pm.response.json();

pm.test('الاستجابة تُرجع رمزاً مميزاً', function () {
  pm.expect(jsonData.token).to.be.a('string').and.not.empty;
});

pm.test('معرف المستخدم موجود', function () {
  pm.expect(jsonData.user.id).to.be.a('number');
});

// تخزين الرمز المميز لكي تتمكن الطلبات الأخرى من إرساله
pm.environment.set('auth_token', jsonData.token);
pm.console.log('تم حفظ الرمز المميز للمستخدم ' + jsonData.user.email);

يحدث شيئان هنا. تؤكد كتل pm.test() أن الاستجابة مشكلة بالطريقة التي تتوقعها، باستخدام أدوات المطابقة pm.expect() من نمط Chai التي يدعمها Apidog أصلاً. ويقوم pm.environment.set('auth_token', jsonData.token) بحفظ الرمز المميز في البيئة. يمكن لأي طلب لاحق الآن إرسال Authorization: Bearer {{auth_token}} دون الحاجة إلى النسخ يدويًا.

النصف الخاص بالتأكيد هنا يستحق الاهتمام بحد ذاته. إن فحوصات ما بعد الاستجابة الجيدة هي ما يحول النقر اليدوي والفحص البصري إلى اختبار حقيقي، ودليلنا حول تأكيدات واجهة برمجة التطبيقات (API assertions) في Apidog يتعمق في أدوات المطابقة والأنماط التي تستحق المعرفة. إذا كنت ترغب أيضًا في إدخال بيانات وهمية واقعية في هذه التدفقات، فإن Faker.js في Apidog يتوافق جيدًا مع إعداد المتغيرات الموضح أعلاه.

زوج من السلوكيات يجب الانتباه إليها في المعالجات اللاحقة. pm.iterationData (بيانات الاختبار الخاصة بك) للقراءة فقط، لذا يمكنك قراءة قيمة مستندة إلى البيانات ولكن لا يمكنك الكتابة إليها من سكريبت. ويعيد pm.cookies ملف تعريف الارتباط من الاستجابة، الملف الذي أرسله الخادم، وليس ملف تعريف الارتباط الذي خرج مع طلبك.

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

بمجرد أن تكون قد كتبت كتلة توقيع HMAC هذه، فمن المحتمل أنك تريدها على أكثر من طلب واحد. يعني نسخها ولصقها في عشر نقاط نهاية وجود عشرة أماكن لإصلاحها عندما تتغير الخوارزمية. إجابة Apidog هي السكريبتات العامة (Public Scripts): مقتطفات قابلة لإعادة الاستخدام تكتبها مرة واحدة وتُرفقها حيثما تدعو الحاجة.

أنشئ واحدًا ضمن الإعدادات (Settings) > السكريبتات العامة (Public Scripts)، ثم أضفه إلى علامة تبويب المعالجات المسبقة (Pre Processors) أو المعالجات اللاحقة (Post Processors) لطلب ما. داخل قائمة المعالجات، يجلس السكريبت العام والسكريبت المخصص جنبًا إلى جنب، ويُهم الترتيب: تنفذ السكريبتات العامة قبل السكريبتات المخصصة في نفس القائمة، وإذا كان لديك عدة سكريبتات عامة، فإنها تعمل من الأعلى إلى الأسفل بالترتيب المذكور.

هناك خدعة واحدة تسبب الارتباك للناس. إذا كنت تريد أن يستدعي سكريبت مخصص دالة معرفة في سكريبت عام، فيجب أن تكون تلك الدالة عامة. إعلان دالة function عادي أو دالة مرتبطة بـ const يكون محليًا لسكريبتها الخاص وغير مرئي للسكريبت التالي. أعلن عنها عن طريق التعيين بدون var أو let أو const:

// في السكريبت العام: اجعل sign() عامة بحذف الكلمة المفتاحية
sign = function (payload, secret) {
  const CryptoJS = require('crypto-js');
  return CryptoJS.HmacSHA256(payload, secret).toString(CryptoJS.enc.Hex);
};
// في السكريبت المخصص تحته: استدعاء الدالة العامة بالاسم
const timestamp = Math.floor(Date.now() / 1000).toString();
const secret = pm.environment.get('payments_api_secret');
pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', sign(timestamp, secret));

أضف السكريبت العام أولاً، ثم ضع السكريبت المخصص تحته، وسيتم حل الاستدعاء. إذا أخطأت في الترتيب أو أضفت const فستحصل على خطأ دالة غير معرفة.

المكتبات، الحزم الخارجية، والتصحيح

الاستيراد crypto-js أعلاه هو واحد من مجموعة مكتبات يضمها Apidog دون الحاجة إلى إعداد. يمكنك require() أي منها مباشرة:

إذا كنت بحاجة إلى شيء غير موجود في تلك القائمة، يمكنك استيراده في وقت التشغيل باستخدام $$.liveRequire()، الذي يجلب الحزمة أثناء التنفيذ:

$$.liveRequire('nanoid', (nanoid) => {
  const id = nanoid.nanoid();
  pm.environment.set('request_id', id);
});

يتطلب هذا المسار اتصالاً بالإنترنت، حيث يقوم Apidog بتنزيل الحزمة عند تشغيل السكريبت. المكتبات المجمعة لا تتطلب ذلك.

عندما يتصرف السكريبت بشكل خاطئ، قم بتصحيح الأخطاء عن طريق التسجيل. يقوم كل من pm.console.log() و console.log() العادي بالطباعة إلى لوحة تحكم Apidog، لذا يمكنك تفريغ توقيع محسوب أو حقل مستخرج ورؤية بالضبط ما أنتجه السكريبت قبل إرسال الطلب أو بعد عودته.

هناك قيدان آخران يستحقان الذكر حتى لا يفاجئاكما. يستخدم pm.sendRequest()، لإطلاق مكالمة HTTP إضافية داخل سكريبت، نمط رد الاتصال بدلاً من الـ Promises، لذا اكتبه باستخدام رد الاتصال، وليس await. و pm.nextRequest() الخاص بـ Postman لتسلسل الطلبات غير مدعوم هنا. عندما تحتاج إلى تنسيق تدفق عمل حقيقي، مع تفرعات وخطوات مشروطة، يستخدم Apidog سيناريوهات الاختبار (Test Scenarios) بدلاً من ذلك، حيث تسلسل الطلبات بصريًا بخطوات الشرط (Condition) وإذا-وإلا (If-Else). إذا كنت تكتب سكريبتات كثيرًا، فإن Apidog Script Generator المدمج يمكنه أيضًا صياغة سكريبت من وصف باللغة الطبيعية ليعطيك نقطة بداية.

أتمتة سير العمل باستخدام Apidog CLI

لا تعمل السكريبتات فقط عندما تنقر على زر الإرسال. عندما تقوم بتجميع طلباتك وتأكيداتك في سيناريو اختبار محفوظ (Test Scenario)، يقوم Apidog CLI بتشغيل هذا السيناريو بالكامل بدون واجهة رسومية، بما في ذلك المعالجات المسبقة واللاحقة (Pre Processors و Post Processors)، وهذا ما يجعل منطق التوقيع واستخراج الرمز المميز جزءًا من CI بدلاً من خطوة يدوية.

قم بتثبيت CLI والمصادقة، ثم قم بتشغيل سيناريو حسب المعرف:

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <SCENARIO_ID> -e <ENV_ID> -r cli

العلامة -t هي معرف سيناريو الاختبار، و -e هي معرف البيئة، و -r يختار المُبلغ (cli، html، أو junit، مفصولة بفواصل لعدة مُبلغين). قم بإنشاء رمز الوصول في إعدادات حساب Apidog الخاص بك، وقم بتصديره كـ APIDOG_ACCESS_TOKEN، والسيناريو نفسه الذي تم تشغيله على سطح المكتب الخاص بك يعمل الآن في CI، بما في ذلك المعالجات المسبقة واللاحقة.

تحذير صريح واحد: قد ينجح سكريبت يعتمد على شيء موجود فقط على جهازك، ملف محلي أو حزمة قمت بتحميلها مرة واحدة، في تطبيق سطح المكتب ثم يفشل في CLI، لأن المُشغل لا يمتلك هذا الاعتماد. حافظ على السكريبتات ضمن المكتبات المجمعة أو $$.liveRequire() لكي تعمل بنفس الطريقة في كل مكان.

الأسئلة الشائعة

هل سكريبتات Apidog متوافقة مع سكريبتات Postman الموجودة لدي؟

نعم في الغالب. يستخدم محرك Apidog نفس واجهة برمجة تطبيقات الكائن pm، لذا فإن pm.environment.set()، pm.response.json()، pm.test()، و pm.expect() كلها تتصرف بالطريقة التي تعرفها. الاختلافان اللذان يجب تذكرهما هما أسماء علامات التبويب، المعالجات المسبقة (Pre Processors) والمعالجات اللاحقة (Post Processors) بدلاً من سكريبت ما قبل الطلب (Pre-request Script) والاختبارات (Tests)، وعدد قليل من الاستدعاءات غير المدعومة مثل pm.nextRequest(). معظم السكريبتات يتم نسخها وتشغيلها.

لماذا تعيد pm.response قيمة غير معرفة (undefined) في سكريبت ما قبل الطلب الخاص بي؟

لأنه لا توجد استجابة بعد. تعمل المعالجات المسبقة (Pre Processors) قبل إرسال الطلب، لذا لم يأتِ شيء لتفحصه. أي كود يقرأ pm.response (حالته، نصه الأساسي، رؤوسه) ينتمي إلى معالج لاحق (Post Processor). إذا كنت بحاجة إلى قيمة في المرحلة المسبقة، استرجعها من pm.request، أو متغير، أو مكتبة بدلاً من ذلك.

كيف أشارك سكريبت واحدًا عبر العديد من الطلبات؟

استخدم السكريبتات العامة (Public Scripts) تحت الإعدادات (Settings) > السكريبتات العامة (Public Scripts). اكتب المنطق مرة واحدة، ثم أرفقه بعلامة تبويب المعالجات المسبقة (Pre Processors) أو المعالجات اللاحقة (Post Processors) لكل طلب، وتذكر أن السكريبتات العامة تعمل قبل السكريبتات المخصصة في نفس القائمة. لاستدعاء دالة من سكريبت عام (Public Script) من سكريبت مخصص (Custom Script)، أعلن عنها كدالة عامة بالتعيين بدون var أو let أو const.

هل يمكنني استيراد حزمة npm لا يضمها Apidog؟

نعم، باستخدام $$.liveRequire('اسم-الحزمة', (pkg) => { ... })، والذي يقوم بتنزيل الحزمة في وقت التشغيل ويتطلب اتصالاً بالإنترنت. لأي شيء موجود في القائمة المدمجة، مثل crypto-js أو moment أو uuid، استخدم require() عاديًا دون الحاجة إلى شبكة. لاحظ أنه يمكنك فقط استيراد وحدة كاملة، وليس مسار وحدة فرعية.

أين أرى ما طبعته السكريبت الخاص بي؟

استخدم pm.console.log() أو console.log() واقرأ المخرجات في لوحة تحكم Apidog بعد إرسال الطلب. إنها أسرع طريقة لتأكيد ما إذا كان التوقيع قد تم حسابه أو الرمز المميز قد تم استخراجه قبل الوثوق به في سيناريو.

الخلاصة

تحول المعالجات المسبقة (Pre Processors) والمعالجات اللاحقة (Post Processors) الطلب الثابت إلى طلب يُجهز نفسه ويتحقق من عمله الخاص. قم بالتوقيع قبل الإرسال، واستخرج وتحقق بعد الاستقبال، وانقل المنطق المشترك إلى السكريبتات العامة (Public Scripts) لكي تكتبه مرة واحدة. تعني واجهة برمجة تطبيقات pm والمكتبات المضمنة أن معظم ما تعرفه من Postman ينتقل مباشرة. افتح Apidog، اختر أي طلب، وأضف أول سكريبت مخصص لك لمشاهدة كلتا المرحلتين تعملان في إرسال واحد. إنه مجاني للبدء، ولا يتطلب بطاقة ائتمان.

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

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