1. 資料庫
  2. HTTP והרשת
  3. קודי סטטוס HTTP

已更新 1 個月前

השרת הבין את הבקשה שלך בצורה מושלמת. הוא פשוט לא יעשה זאת בדרך הזו.

זה מה שאומר 405 Method Not Allowed. נקודת הקצה קיימת. השרת זיהה מה ביקשת. אבל שיטת ה-HTTP שבה השתמשת — DELETE, POST, PUT, או כל אחרת — אינה מתקבלת בנקודת קצה זו. דפקת על הדלת הנכונה, אבל שאלת את השאלה הלא נכונה.

מבנה תגובת 405

כשנתקלים ב-405, התגובה מספרת לך מה השתבש וכיצד לתקן זאת:

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
Content-Type: application/json

{
    "error": "Method Not Allowed",
    "message": "DELETE method is not supported for this endpoint",
    "allowedMethods": ["GET", "POST"]
}

כותרת ה-Allow אינה עיטור אופציונלי — היא נדרשת על פי מפרט ה-HTTP. השרת חייב לומר לך אילו שיטות הוא מקבל. זוהי עזרה מצד השרת: "אינך יכול לבצע DELETE כאן, אבל אתה יכול לבצע GET או POST."

מדוע נקודות קצה דוחות שיטות

חלק מנקודות הקצה הן לקריאה בלבד מעצם תכנונן:

POST /api/status HTTP/1.1

HTTP/1.1 405 Method Not Allowed
Allow: GET

נקודת הקצה של הסטטוס קיימת כדי לדווח על מידע, לא לקבל אותו. POST אינו הגיוני כאן.

חלק מהמשאבים לא אמורים להימחק דרך ה-API:

DELETE /api/users HTTP/1.1

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST

ניתן לקבל רשימת משתמשים (GET) וליצור משתמשים (POST), אבל מחיקה המונית אינה חשופה. אולי זהו אמצעי בטיחות. אולי המחיקה מתרחשת דרך תהליך אחר. נקודת הקצה מחליטה אילו פעולות הגיוניות למטרתה.

ארבעה סוגי סירוב

ל-HTTP יש כמה דרכים לומר לא, וכל אחת מהן אומרת דבר אחר:

404 Not Found: "אני לא יודע על מה אתה מדבר."

GET /api/nonexistent
HTTP/1.1 404 Not Found

נקודת הקצה אינה קיימת כלל.

405 Method Not Allowed: "אני יודע מה אתה רוצה, אבל אני לא אעשה זאת בדרך הזו."

DELETE /api/users
HTTP/1.1 405 Method Not Allowed
Allow: GET, POST

נקודת הקצה קיימת אך אינה מקבלת שיטה זו.

403 Forbidden: "אתה ספציפית אינך מורשה לעשות זאת."

DELETE /api/users/123
HTTP/1.1 403 Forbidden

השיטה עשויה להיות תקינה, אבל אין לך הרשאה.

501 Not Implemented: "אני אפילו לא מכיר את השיטה הזו."

WEIRDMETHOD /api/users
HTTP/1.1 501 Not Implemented

השרת אינו מזהה את שיטת ה-HTTP עצמה.

ההבחנה חשובה לצורך איתור תקלות. 404 אומר לבדוק את ה-URL. 405 אומר לבדוק את השיטה. 403 אומר לבדוק את פרטי ההזדהות. 501 אומר שכנראה אתה עושה משהו חריג.

יישום 405 כהלכה

התבנית פשוטה — הגדר את השיטות שאתה תומך בהן, ודחה את כל השאר:

app.route('/api/users')
    .get(function(request, response) {
        response.json(users);
    })
    .post(function(request, response) {
        createUser(request.body);
        response.status(201).json({success: true});
    })
    .all(function(request, response) {
        response.status(405)
            .set('Allow', 'GET, POST, OPTIONS')
            .json({
                error: 'Method Not Allowed',
                allowedMethods: ['GET', 'POST', 'OPTIONS']
            });
    });

הטיפול ב-.all() תופס כל שיטה שאינה מוגדרת במפורש מעליו. כל תגובת 405 כוללת את כותרת ה-Allow — זו לא רק שיטה מומלצת, היא חובה.

אל תשכח את OPTIONS

שיטת OPTIONS שואלת "מה אני יכול לעשות כאן?" השרתים צריכים לענות:

OPTIONS /api/users HTTP/1.1

HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE, OPTIONS

כך פועלות בקשות ה-CORS preflight — הדפדפן שואל OPTIONS לפני שהוא מבצע בקשות cross-origin. אם השרת שלך מחזיר 405 עבור OPTIONS, תשבור את CORS עבור לקוחות שמנסים להשתמש ב-API שלך מדפדפנים.

טיפול ב-405 כלקוח

כאשר מקבלים תגובת 405, כותרת ה-Allow מראה לך מה לעשות במקום:

async function makeRequest(url, method, data) {
    const response = await fetch(url, {
        method: method,
        headers: { 'Content-Type': 'application/json' },
        body: data ? JSON.stringify(data) : undefined
    });

    if(response.status === 405) {
        const allowHeader = response.headers.get('Allow');
        const allowedMethods = allowHeader ? allowHeader.split(', ') : [];
        
        throw new Error(
            `${method} not allowed. Try: ${allowedMethods.join(', ')}`
        );
    }

    return response;
}

סמנטיקת שיטות RESTful

ב-REST, לכל שיטה יש משמעות ספציפית:

  • GET: אחזור משאבים (בטוח, אידמפוטנטי)
  • POST: יצירת משאבים חדשים
  • PUT: החלפת משאבים במלואם (אידמפוטנטי)
  • PATCH: עדכון חלקי של משאבים
  • DELETE: הסרת משאבים (אידמפוטנטי)

נקודות קצה צריכות לקבל רק שיטות שהגיוניות מבחינה סמנטית:

// אוסף: רשימה ויצירה
app.route('/api/users')
    .get(listUsers)
    .post(createUser)
    .all(methodNotAllowed(['GET', 'POST', 'OPTIONS']));

// משאב בודד: קריאה, עדכון, מחיקה
app.route('/api/users/:id')
    .get(getUser)
    .put(replaceUser)
    .patch(updateUser)
    .delete(deleteUser)
    .all(methodNotAllowed(['GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']));

לא ניתן לבצע DELETE על אוסף (זה יהיה מסוכן). לא ניתן לבצע POST על משאב ספציפי (POST יוצר דברים חדשים, הוא אינו משנה דברים קיימים). ההגבלות האלה אינן שרירותיות — כך REST שומר על סמנטיקה צפויה.

שאלות נפוצות על 405 Method Not Allowed

מדוע אני מקבל 405 כשנקודת הקצה שלי בהחלט קיימת?

זה בדיוק מה ש-405 אומר — נקודת הקצה קיימת, אבל היא אינה מקבלת את שיטת ה-HTTP שבה אתה משתמש. בדוק את כותרת ה-Allow בתגובה כדי לראות אילו שיטות נתמכות, ואז התאם את הבקשה שלך בהתאם.

האם כותרת ה-Allow באמת נדרשת?

כן. RFC 7231 קובע כי תגובת 405 "חייבת" לכלול כותרת Allow המפרטת את השיטות שמשאב היעד תומך בהן. השמטתה מפרת את מפרט ה-HTTP ומקשה על לקוחות לאתר תקלות.

האם לחזור 404 או 405 עבור נקודת קצה שקיימת אך אין לה טיפולים מוגדרים?

אם תבנית ה-URL תואמת מסלול ביישום שלך, החזר 405 עם השיטות שאתה כן תומך בהן (גם אם מדובר ב-OPTIONS בלבד). החזר 404 רק כאשר ה-URL עצמו אינו מתאים לאף משאב במערכת שלך.

כיצד 405 מתקשר עם CORS?

דפדפנים שולחים בקשת OPTIONS preflight לפני בקשות cross-origin עם שיטות מסוימות. אם השרת שלך מחזיר 405 עבור OPTIONS, ה-preflight נכשל והבקשה האמיתית לעולם לא מתרחשת. טפל תמיד בבקשות OPTIONS, גם אם רק כדי להחזיר את כותרת ה-Allow.

此頁面對您有幫助嗎?

😔
🤨
😃