إرسال رمز مميز ناتج عن الحل في طلب JSON باستخدام Playwright
اعترض طلب POST المعروف للتطبيق بصيغة JSON واستبدل حقل CAPTCHA فيه بـ solution.token. لن يفيد ملء حقل textarea إذا كان التطبيق يبني طلبه من حالة JavaScript.
يستهدف المثال أدناه نقطة نهاية إرسال من الأصل نفسه في تطبيق تملكه. ويحافظ على حقول JSON الأخرى وترويسات الطلب بدلًا من إعادة بناء الطلب.
في هذه الصفحة
كيّف المثال مع تطبيقك
- 1.
جهّز خدمة الحل
استخدم Node.js 22+ وPlaywright وحزمة SDK الرسمية لـJavaScript. اتبع تعليمات تثبيت SDK؛ استخدم تنزيل الحزمة الموثّق بدلاً من افتراض توفرها في سجل npm. احتفظ بـ
SOLVETHREE_API_KEYداخل عملية Node.js، لا في شيفرة المتصفح. - 2.
إعداد الموقع والوكيل
اضبط
TARGET_URLعلى صفحة اختبار تملكها، وSOLVETHREE_PROXYعلى عنوان URL لوكيل HTTP أو HTTPS الخاص بها. يطلب المثال الإجراءloginلاسم مضيف الصفحة. يحتاج اسم المضيف هذا إلى ملف تعريف نشط في مساحة العمل؛ أعدّ ملف تعريف الموقع أولاً. غيّر الإجراء إذا كان تطبيقك يستخدم إجراءً آخر. - 3.
تحديد طلب الإرسال بدقة
اضبط
TARGET_SUBMIT_URLعلى نقطة نهاية POST الخاصة بـJSON، بما في ذلك مسارها. يجب أن تشترك مع الصفحة في الأصل نفسه. يتوقع المثال كائناً يحتوي علىrecaptchaTokenوزراً اسمه الميسّر هوSubmitبالضبط. غيّر هذه التفاصيل الخاصة بالتطبيق معاً.
لإعداد بيئة اختبار، استخدم صفحة ترسل كائن JSON إلى نقطة النهاية تلك وتعيد استجابة يمكن فحصها. أضف حقلاً آخر وحقل CSRF حتى تتمكن من التحقق من عدم تغيّر أيٍّ منهما. يمكن لبيئة اختبار محلية تكتفي بإعادة البيانات المستلمة أن توضح إعادة كتابة JSON، لكنها لا تتحقق من قبول CAPTCHA. يظل المثال المرفق ينفّذ عملية حل فعلية ويتطلب موقعاً مُعدّاً يمكن الوصول إليه عبر الوكيل.
الحل والاعتراض والإرسال
import { chromium } from 'playwright';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const target = new URL(process.env.TARGET_URL);
const proxy = new URL(process.env.SOLVETHREE_PROXY);
const result = await client.solve({ site: target.hostname, action: 'login', proxy: process.env.SOLVETHREE_PROXY });
const proxyConfig = { server: `${proxy.protocol}//${proxy.host}`, username: decodeURIComponent(proxy.username), password: decodeURIComponent(proxy.password) };
const submit = new URL(process.env.TARGET_SUBMIT_URL);
if (submit.origin !== target.origin) throw new Error('Use this demo with a same-origin submission URL');
const browser = await chromium.launch();
try {
const context = await browser.newContext({ proxy: proxyConfig, userAgent: result.solution.userAgent,
extraHTTPHeaders: { 'sec-ch-ua': result.solution.secChUa } });
const page = await context.newPage();
await page.route(submit.href, async route => {
if (route.request().method() !== 'POST') return route.continue();
const body = route.request().postDataJSON();
if (!body || typeof body !== 'object' || Array.isArray(body)) throw new Error('Expected the known JSON object');
await route.continue({ postData: JSON.stringify({ ...body, recaptchaToken: result.solution.token }),
headers: { ...route.request().headers(), 'content-type': 'application/json' } });
});
await page.goto(target.href);
const outcome = page.waitForResponse(r => r.url() === submit.href && r.request().method() === 'POST');
await page.getByRole('button', { name: 'Submit', exact: true }).click();
console.log('Application HTTP status:', (await outcome).status());
// recaptchaToken, the Submit button and this endpoint belong to this demo app.
// Adapt them to the real application, retaining its session/CSRF data.
await context.close();
} finally { await browser.close(); }ينشئ client.solve المهمة ويستعلم دورياً حتى تصبح جاهزة أو يرمي استثناءً. ينشئ المثال بعد ذلك سياق متصفح باستخدام solution.userAgent وsolution.secChUa والوكيل الواحد نفسه الممرَّر إلى عملية الحل. لا تطبّق SDK الحل على المتصفح؛ يتولى معالج المسار ذلك.
سياق المتصفح جديد. إذا كان الإرسال يتطلب مصادقة أو إعداداً آخر للجلسة، فنفّذ ذلك في هذا السياق قبل الإرسال. لا يستورد المثال جلسة متصفح موجودة.
استبدال الرمز، لا الطلب بأكمله
يُسجَّل المسار قبل الانتقال إلى الصفحة ويقتصر على عنوان URL المُعدّ للإرسال. تمر الطلبات غير POST دون تغيير. أما في طلب POST، فيقرأ المعالج كائن JSON الموجود وينسخ حقوله ويستبدل recaptchaToken فقط.
يحافظ ذلك على حقول متن الطلب، مثل قيم النموذج وبيانات CSRF. ينسخ المعالج أيضاً ترويسات الطلب ويضبط نوع المحتوى على JSON. حافظ على سلوك الجلسة وCSRF الحالي في التطبيق؛ فرمز الحل لا يحل محل أيٍّ منهما.
لا توسّع نطاق المسار ليشمل كل الطلبات، ولا تستبدل أي حقل لمجرد أنه يشبه رمزاً. افحص الطلب الصادر من التطبيق الذي تملكه واستخدم اسم الحقل الفعلي فيه. لا يكتشف هذا المثال عناصر واجهة CAPTCHA، ولا يستدعي دوال رد نداء عشوائية، ولا يدعم صفحات أطراف ثالثة عشوائية. تشرح وثائق الشبكة في Playwright آلية الاعتراض.
افحص استجابة التطبيق
يبدأ انتظار الاستجابة قبل النقر ويطابق عنوان URL للإرسال وطريقة POST. تخص الحالة المسجَّلة استجابة التطبيق، لا مهمة solvethree. افحص متن تلك الاستجابة أو الحالة الناتجة في التطبيق وفق معايير النجاح الخاصة به. لا تثبت جاهزية المهمة ولا حالة نجاح HTTP وحدها أن التطبيق قبِل الرمز.
- لا ينتهي انتظار الاستجابة أبداً.
تحقق مما إذا كان زر Submit المحدد يطلق طلب POST إلى عنوان URL المُعدّ.
جرّب هذا: صحّح محدِّد الزر أو نقطة النهاية أو الطريقة لتطابق التطبيق. لا توسّع الاعتراض ليشمل حركة بيانات غير ذات صلة.
- يتعذر على المسار قراءة كائن JSON.
افحص متن الطلب ونوع المحتوى.
جرّب هذا: استخدم هذا المعالج فقط لنقطة النهاية المعروفة التي تستقبل كائن JSON. تتطلب بيانات النماذج والمصفوفات وتنسيقات الحمولة الأخرى معالجة مختلفة.
- المهمة جاهزة، لكن التطبيق يرفض الإرسال.
افحص JSON الصادر بحثاً عن
solution.token، ثم تحقق من بيانات الجلسة/CSRF والإجراء وهوية المتصفح المُعادة والوكيل.جرّب هذا: صحّح الطلب غير المتطابق قبل الدفع مقابل عملية حل أخرى. أبقِ المتصفح على الوكيل المستخدم في الحل واستخدم الهوية المُعادة.
- تفشل عملية الحل قبل فتح المتصفح.
ميّز بين خطأ في طلب HTTP وفشل نهائي للمهمة. إذا فشلت المهمة، فافحص
errorCodeوerror.جرّب هذا: أصلح مشكلة المدخلات أو ملف التعريف أو الاتصال المُبلَّغ عنها بدلاً من إعادة المحاولة بالمدخلات نفسها دون تغيير. راجع معالجة أخطاء API.
المصادر ومرجع API
شغّل مهمتك الأولى.
ابدأ برصيد قدره $5 في مساحة العمل.