1. ספרייה
  2. HTTP והרשת
  3. קודי סטטוס HTTP

עודכן לפני חודש

שגיאת 400 Bad Request היא השרת שמושיט יד: "אני מקשיב, אני רוצה לטפל בבקשה שלך, אבל אני לא מצליח להבין מה אתה אומר."

בשונה משגיאות 5xx (השרת קרס) או 401/403 (אין לך הרשאה), שגיאת 400 אומרת שהשיחה נכשלה לפני שהתחילה. השרת קיבל את הבקשה שלך, ניסה להבין אותה — ולא הצליח. התיקון תמיד נמצא בצד הלקוח.

מה גורם ל-400

הבקשה עצמה שבורה. השרת אפילו לא יכול להבין מה אתה מבקש.

JSON שגוי — הסיבה הנפוצה ביותר:

POST /api/users HTTP/1.1
Content-Type: application/json

{
    "name": "Alice"
    "email": "alice@example.com"
}

הפסיק החסר אחרי "Alice" גורם לכך שהשרת מקבל זבל במקום נתונים. הבעיה היא לא שהערכים שלך שגויים — השרת אפילו לא יכול לראות את הערכים שלך.

שדות חובה חסרים:

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Alice"}

אם ה-API דורש שדה email ואתה לא שולח אותו, השרת לא יכול להמשיך. זה כמו למלא טופס ולהשאיר את שורת החתימה ריקה.

סוגים שגויים:

{"age": "twenty-five"}

כשהשרת מצפה למספר ומקבל מחרוזת, הוא לא יכול לנחש בבטחה מה התכוונת. האם התכוונת ל-25? ל-20? השרת מסרב להניח הנחות.

ערכים לא תקינים:

{"email": "not-an-email"}

המבנה תקין, אבל התוכן לא עובר ולידציה. שדה email שלא מכיל כתובת אימייל — זו בקשה שהשרת לא יכול לבצע.

400 מול קודי שגיאה אחרים

בחירת קוד השגיאה הנכון אומרת ללקוחות מה השתבש ומה הם יכולים לעשות בנידון.

400 מול 401: השתמש ב-400 כשמבנה הבקשה שבור. השתמש ב-401 כשהבקשה תקינה אבל המשתמש לא מאומת. "ה-JSON שלך לא תקין" — זה 400. "אתה צריך להתחבר" — זה 401.

400 מול 403: השתמש ב-400 לבקשות עם פורמט שגוי. השתמש ב-403 כשהבקשה תקינה אבל למשתמש אין הרשאה. "פורמט אימייל לא תקין" — זה 400. "אתה לא יכול למחוק חשבונות של משתמשים אחרים" — זה 403.

400 מול 404: השתמש ב-400 כשהבקשה עצמה שגויה. השתמש ב-404 כשהבקשה תקינה אבל המשאב לא קיים. "פורמט מזהה משתמש לא תקין" — זה 400. "משתמש 12345 לא קיים" — זה 404.

400 מול 422: ההבחנה עדינה אך משמעותית. 400 אומר "אני לא יכול לפענח את הבקשה שלך" — שגיאות תחביר, JSON שגוי, כותרות חסרות. 422 אומר "אני מבין את הבקשה שלך אבל היא לא הגיונית" — כמו ניסיון ליצור משתמש עם כתובת אימייל שכבר קיימת. הבקשה מעוצבת היטב אבל בלתי אפשרית מבחינה סמנטית.

בפועל, API-ים רבים משתמשים ב-400 לשני המקרים. אבל אם אתה רוצה דיוק: 400 הוא שטות, 422 הוא סתירה לוגית.

כתיבת תגובות שגיאה שימושיות

תגובת שגיאה רזה כמו {"error": "Bad Request"} לא עוזרת לאף אחד. כל הנקודה של 400 היא לעזור ללקוח לתקן את הבקשה שלו.

תגיד להם מה השתבש:

{
    "error": "Validation failed",
    "details": [
        {"field": "email", "message": "Invalid email format"},
        {"field": "age", "message": "Must be between 0 and 150"}
    ]
}

הראה להם איך לתקן:

{
    "error": "Invalid date format",
    "expected": "YYYY-MM-DD",
    "received": "10/21/2024",
    "example": "2024-10-21"
}

כלול קודים קריאים למכונה:

{
    "error": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": [
        {"field": "email", "code": "INVALID_FORMAT"}
    ]
}

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

מימוש בצד השרת

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

app.post('/api/users', function(request, response) {
    const errors = [];
    
    if(!request.body.email) {
        errors.push({field: 'email', message: 'Email is required'});
    }
    else if(!isValidEmail(request.body.email)) {
        errors.push({field: 'email', message: 'Invalid email format'});
    }
    
    if(errors.length > 0) {
        return response.status(400).json({
            error: 'Validation failed',
            details: errors
        });
    }
    
    // מגיעים לכאן רק עם נתונים תקינים
    createUser(request.body);
});

השתמש בספריות ולידציה במקום לכתוב בדיקות בעצמך:

const Joi = require('joi');

const userSchema = Joi.object({
    name: Joi.string().required(),
    email: Joi.string().email().required(),
    age: Joi.number().min(0).max(150)
});

app.post('/api/users', function(request, response) {
    const { error, value } = userSchema.validate(request.body);
    
    if(error) {
        return response.status(400).json({
            error: 'Validation failed',
            details: error.details.map(function(d) {
                return {field: d.path.join('.'), message: d.message};
            })
        });
    }
    
    // value מכיל נתונים מאומתים ומנוקים
});

טיפול בצד הלקוח

הדבר החשוב לגבי שגיאות 400: אל תנסה שוב באופן אוטומטי. בשונה מ-503 (שרת עמוס זמנית), שגיאת 400 לא תצליח באורח פלא בניסיון השני. הבקשה שבורה. היא תישאר שבורה עד שמישהו יתקן אותה.

async function createUser(userData) {
    const response = await fetch('/api/users', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(userData)
    });
    
    if(response.status === 400) {
        const error = await response.json();
        
        // הצג למשתמש מה השתבש
        if(error.details) {
            error.details.forEach(function(detail) {
                showFieldError(detail.field, detail.message);
            });
        }
        
        // אל תנסה שוב — תן למשתמש לתקן את הטופס
        throw new ValidationError(error);
    }
    
    return response.json();
}

שיקול אבטחה

הודעות שגיאה צריכות לעזור למשתמשים לגיטימיים לתקן את הבקשות שלהם — מבלי לעזור לתוקפים לחקור את המערכת שלך. "כתובת האימייל כבר קיימת" — בסדר. "Database constraint violation on users.email unique index" — חושף את התשתית שלך.

שאלות נפוצות על 400 Bad Request

האם להשתמש ב-400 או ב-422 לשגיאות ולידציה?

שניהם סבירים. מבחינה קפדנית, 400 מיועד לבקשות עם בעיות תחביריות (JSON שגוי, כותרות חסרות) ואילו 422 מיועד לבקשות תקינות מבחינה תחבירית שנכשלות בלוגיקה עסקית (אימייל כפול, טווח תאריכים לא תקין). API-ים רבים מפשטים ומשתמשים ב-400 לכל שגיאות הולידציה. בחר גישה אחת והיה עקבי.

מדוע ה-API שלי מחזיר 400 כשה-JSON נראה תקין?

תווים בלתי נראים הם לרוב האשמים. העתקה-הדבקה מעורכי טקסט עשיר, תווי רווח מסוימים ב-Unicode, או סימני סדר בתים (BOM) עלולים לפגום ב-JSON ללא ראיות גלויות. נסה להקליד מחדש את ה-JSON ידנית, או השתמש בכלי ולידציה ל-JSON שמציג תווים מוסתרים.

האם תגובות 400 צריכות לכלול את הנתונים הלא תקינים שנשלחו?

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

כמה מפורטות צריכות להיות הודעות שגיאה 400?

מפורטות מספיק שמפתח יוכל לתקן את הבעיה בלי לנחש. "Invalid request" — חסר תועלת. "Field 'email' must be a valid email address, received 'not-an-email'" — ניתן לפעול לפיו. המטרה היא לצמצם את זמן ניפוי הבאגים.

האם דף זה היה מועיל?

😔
🤨
😃
400 Bad Request • ספרייה • Connected