שליחת טוקן שנפתר בבקשת JSON של Playwright

מאת solvethree4 דקות קריאה

יירטו את בקשת ה-POST המוכרת של היישום בפורמט JSON והחליפו את שדה ה-CAPTCHA שלה ב-solution.token. מילוי textarea לא יעזור אם היישום בונה את הבקשה שלו מתוך המצב ב-JavaScript.

הדוגמה הבאה מיועדת לנקודת קצה לשליחה באותו מקור, ביישום שבבעלותכם. היא משמרת את שדות ה-JSON האחרים ואת כותרות הבקשה במקום לבנות את הבקשה מחדש.

בדף הזה

התאימו את הדוגמה ליישום שלכם

  1. 1.

    הכינו את שירות הפתרון

    השתמשו ב-Node.js 22+, ב-Playwright וב-SDK הרשמי ל-JavaScript. פעלו לפי הוראות התקנת ה-SDK; השתמשו בהורדת החבילה המתועדת במקום להניח שהיא זמינה במאגר npm. שמרו את SOLVETHREE_API_KEY בתהליך Node.js, ולא בקוד הדפדפן.

  2. 2.

    הגדרת האתר והפרוקסי

    הגדירו את TARGET_URL ככתובת דף הבדיקה שבבעלותכם ואת SOLVETHREE_PROXY ככתובת פרוקסי ה-HTTP או ה-HTTPS שלו. הדוגמה מבקשת את הפעולה login עבור שם המארח של הדף. לשם המארח הזה דרוש פרופיל פעיל בסביבת העבודה; תחילה הגדירו את פרופיל האתר. שנו את הפעולה אם היישום שלכם משתמש בפעולה אחרת.

  3. 3.

    זיהוי בקשת השליחה המדויקת

    הגדירו את TARGET_SUBMIT_URL כנקודת הקצה ל-POST של JSON, כולל הנתיב שלה. היא חייבת להיות באותו מקור כמו הדף. הדוגמה מצפה לאובייקט שמכיל recaptchaToken ולכפתור שהשם הנגיש שלו הוא בדיוק Submit. שנו יחד את הפרטים האלה, הספציפיים ליישום.

לצורך סביבת בדיקה, השתמשו בדף ששולח אובייקט JSON לנקודת הקצה הזאת ומחזיר תגובה שאפשר לבדוק. כללו שדה נוסף ושדה CSRF כדי שתוכלו לוודא שאף אחד מהם לא משתנה. סביבת בדיקה מקומית שרק מחזירה את הקלט יכולה להדגים את שינוי ה-JSON, אך אינה מאמתת שה-CAPTCHA התקבל. הדוגמה שסופקה עדיין מבצעת פתרון אמיתי ודורשת אתר מוגדר שנגיש דרך הפרוקסי.

פתרון, יירוט ושליחה

Playwright · החלפת פרמטר אסימון JSON מוכר אחד
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 אינו מחיל את הפתרון על הדפדפן; פונקציית הטיפול בנתיב עושה זאת.

הקשר הדפדפן חדש. אם השליחה דורשת אימות או הגדרה אחרת של סשן, בצעו זאת בהקשר הזה לפני השליחה. הדוגמה אינה מייבאת סשן דפדפן קיים.

החליפו את הטוקן, לא את הבקשה כולה

הנתיב נרשם לפני הניווט ומוגבל לכתובת השליחה שהוגדרה. בקשות שאינן POST ממשיכות ללא שינוי. בבקשת POST, פונקציית הטיפול קוראת את אובייקט ה-JSON הקיים, מעתיקה את השדות שלו ומחליפה רק את recaptchaToken.

כך נשמרים שדות גוף הבקשה, כגון ערכי טופס ונתוני CSRF. פונקציית הטיפול גם מעתיקה את כותרות הבקשה ומגדירה את סוג התוכן כ-JSON. שמרו על התנהגות הסשן וה-CSRF הקיימת של היישום; טוקן שנפתר אינו מחליף אף אחד מהם.

אל תרחיבו את הנתיב לכל הבקשות ואל תחליפו שדה כלשהו רק משום שהוא נראה כמו טוקן. בדקו את הבקשה היוצאת מהיישום שבבעלותכם והשתמשו בשם השדה בפועל. הדוגמה הזאת אינה מאתרת וידג'טים, מפעילה פונקציות callback שרירותיות או תומכת בדפי צד שלישי שרירותיים. תיעוד הרשת של Playwright מסביר את מנגנון היירוט.

בדקו את תגובת היישום

ההמתנה לתגובה מתחילה לפני הלחיצה ומתאימה לכתובת השליחה ולשיטת POST. הסטטוס שנרשם ביומן שייך לתגובת היישום — לא למשימת solvethree. בדקו את גוף התגובה או את המצב שהתקבל ביישום לפי קריטריוני ההצלחה שלו. לא משימה מוכנה ולא סטטוס HTTP של הצלחה לבדם מוכיחים שהיישום קיבל את הטוקן.

ההמתנה לתגובה אינה מסתיימת.

בדקו אם כפתור Submit המדויק מפעיל בקשת POST לכתובת שהוגדרה.

כדאי לנסות: תקנו את מאתר הכפתור, נקודת הקצה או השיטה כך שיתאימו ליישום. אל תרחיבו את היירוט לתעבורה לא קשורה.

הנתיב אינו מצליח לקרוא אובייקט JSON.

בדקו את גוף הבקשה ואת סוג התוכן.

כדאי לנסות: השתמשו בפונקציית הטיפול הזאת רק עבור נקודת הקצה המוכרת שמקבלת אובייקט JSON. נתוני טופס, מערכים ופורמטים אחרים של תוכן הבקשה דורשים טיפול אחר.

המשימה מוכנה, אך היישום דוחה את השליחה.

בדקו אם ה-JSON היוצא מכיל את solution.token, ולאחר מכן בדקו את נתוני הסשן/CSRF, הפעולה, זהות הדפדפן שהוחזרה והפרוקסי.

כדאי לנסות: תקנו את אי-ההתאמה בבקשה לפני שתשלמו על פתרון נוסף. השאירו את הדפדפן על הפרוקסי ששימש לפתרון והשתמשו בזהות שהוחזרה.

הפתרון נכשל לפני פתיחת הדפדפן.

הבחינו בין שגיאה בבקשת HTTP לבין כשל סופי של משימה. במשימה שנכשלה, בדקו את errorCode ואת error.

כדאי לנסות: תקנו את בעיית הקלט, הפרופיל או הקישוריות שדווחה במקום לנסות שוב עם קלט ללא שינוי. ראו טיפול בשגיאות API.

הפעלת המשימה הראשונה שלך.

התחילו עם $5 בקרדיט לסביבת העבודה.

יצירת סביבת עבודה
שליחת טוקן שנפתר בבקשת JSON של Playwright · solvethree