Lỗi 405 Method Not Allowed là gì? Cách khắc phục

Advertisement
Lỗi 405 Method Not Allowed là gì?
405 Method Not Allowed là mã trạng thái HTTP có nghĩa là máy chủ biết địa chỉ bạn yêu cầu, nhưng không cho phép phương thức mà yêu cầu của bạn sử dụng. RFC 9110 (mục 15.5.6) định nghĩa đây là trường hợp phương thức "được máy chủ gốc biết đến nhưng không được tài nguyên đích hỗ trợ".
Mỗi yêu cầu HTTP đều có một phương thức: GET để đọc trang, POST để gửi biểu mẫu hoặc tạo dữ liệu, PUT và PATCH để cập nhật, DELETE để xóa, OPTIONS để hỏi những gì được phép. Lỗi 405 nghĩa là URL có tồn tại, nhưng không dành cho phương thức đó. Nếu URL hoàn toàn không tồn tại, bạn sẽ nhận được lỗi 404.
Vì lỗi này liên quan đến cách yêu cầu được gửi chứ không phải một trang bị thiếu, lỗi 405 gần như luôn là việc mà nhà phát triển của trang web cần khắc phục. Khách truy cập thường gặp nó sau khi gửi biểu mẫu hoặc mở một liên kết đã lỗi thời.
Lỗi 405 trông như thế nào
| Máy chủ / framework | Thông báo thường gặp |
|---|---|
| nginx | 405 Not Allowed (kèm dòng nginx bên dưới) |
| Apache | Method Not Allowed. The requested method POST is not allowed for this URL. |
| IIS | HTTP Error 405.0 - Method Not Allowed. The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used. |
| Next.js / API | Phản hồi trống hoặc JSON với mã trạng thái 405, thường chỉ thấy được trong DevTools |
| Console của trình duyệt (CORS) | Một lỗi CORS, vì yêu cầu preflight OPTIONS nhận về mã 405 |
Advertisement
Bước 1: Đọc header Allow
Hãy hỏi máy chủ xem nó chấp nhận những phương thức nào cho URL đó. Gửi một yêu cầu OPTIONS, hoặc lặp lại yêu cầu bị lỗi kèm hiển thị header:
# URL này chấp nhận những phương thức nào?
curl -i -X OPTIONS https://example.com/api/contact
# Lặp lại yêu cầu bị lỗi và xem mã trạng thái cùng header Allow
curl -i -X POST https://example.com/api/contact -d 'name=test'
# HTTP/2 405
# allow: GET, HEADCông cụ Kiểm Tra Header HTTP của DNS Robot hiển thị mã trạng thái và các header mà một URL trả về cho yêu cầu GET thông thường, rất hữu ích khi bạn kiểm tra một trang trên trình duyệt thay vì một API.
Không phải máy chủ nào cũng tuân thủ quy tắc này. Ví dụ, trang 405 mặc định của nginx được gửi đi mà không có header Allow, nên trên nginx bạn cần kiểm tra xem khối location nào đang xử lý URL đó (Cách 2).
Nếu bạn là khách truy cập
Quay lại và tải lại trang, sau đó gửi lại biểu mẫu. Một biểu mẫu được tải từ bản lưu trong bộ nhớ đệm cũ có thể gửi dữ liệu đến một địa chỉ đã thay đổi.
Đừng làm mới trang sau khi gửi. Làm mới một trang là kết quả của biểu mẫu có thể gửi lại yêu cầu POST đến một URL chỉ chấp nhận GET.
Kiểm tra địa chỉ xem có lỗi chính tả không, hoặc mở trang chủ của trang web và điều hướng lại.
Báo lỗi. Nếu một biểu mẫu trên trang web luôn bị lỗi, chủ trang web cần khắc phục, vì vậy hãy gửi cho họ địa chỉ của trang đó.
Advertisement
Cách 1: Gửi đúng phương thức đến đúng URL
Nguyên nhân phổ biến nhất trong code đơn giản là sự không khớp: một biểu mẫu hoặc lệnh gọi fetch() dùng POST trong khi endpoint chỉ chấp nhận GET, hoặc yêu cầu được gửi đến URL của trang thay vì URL của API. Hãy so sánh phương thức trong code của bạn với header Allow và tài liệu của API.
// Endpoint chỉ cho phép POST, nên một yêu cầu GET (mặc định của fetch) sẽ trả về 405
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Ana" }),
})
if (res.status === 405) console.log("Allowed:", res.headers.get("allow"))Cách 2: nginx trả về 405 cho yêu cầu POST đến tệp tĩnh
Trình xử lý tệp tĩnh của nginx chỉ phục vụ GET và HEAD. Một yêu cầu POST gửi đến tệp .html, hoặc đến một location phục vụ tệp thay vì chuyển yêu cầu cho ứng dụng của bạn, sẽ nhận về 405 Not Allowed. Điều này thường xảy ra khi thuộc tính action của biểu mẫu trỏ đến một trang tĩnh, hoặc khi khối location dành cho ứng dụng của bạn không khớp.
Cách khắc phục thực sự là gửi yêu cầu POST đến một ứng dụng (PHP, Node, Python) bằng proxy_pass hoặc fastcgi_pass trong đúng khối location. Hãy kiểm tra xem khối nào đang xử lý URL:
# Dữ liệu biểu mẫu phải đến được ứng dụng, không phải trình xử lý tệp tĩnh
location /api/ {
proxy_pass http://127.0.0.1:3000;
}
# Kiểm tra và tải lại cấu hình sau khi thay đổi
# sudo nginx -t && sudo systemctl reload nginxAdvertisement
Cách 3: IIS chặn PUT và DELETE (WebDAV)
Trên máy chủ Windows chạy IIS, module WebDAV chiếm quyền xử lý các phương thức PUT và DELETE, nên các REST API (ASP.NET Web API và các API khác) trả về HTTP Error 405.0 cho chúng. Nếu bạn không dùng WebDAV, hãy gỡ nó khỏi trang web của bạn trong web.config:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>Hãy kiểm tra thêm phần cài đặt Request Filtering của trang web trong IIS Manager (thẻ HTTP Verbs), nơi có thể từ chối hẳn một số phương thức (IIS báo các trường hợp này là 404.6, không phải 405).
Cách 4: Thêm phương thức vào route handler
Các framework trả về 405 khi một route tồn tại nhưng không có handler cho phương thức được dùng:
Next.js (App Router): một tệp
route.tschỉ trả lời các phương thức mà nó export. Nếu nó exportGETmà không exportPOST, yêu cầu POST sẽ trả về 405. Hãy thêmexport async function POST(request: Request) { … }.Flask: route mặc định chỉ chấp nhận GET. Hãy dùng
@app.route("/contact", methods=["GET", "POST"]).Django: các class-based view trả về 405 cho những phương thức không có handler tương ứng (hãy thêm phương thức
post()), và decoratorrequire_http_methodscũng hoạt động tương tự.Express: mặc định, một phương thức không khớp sẽ rơi xuống 404 chứ không phải 405. Nếu API của bạn cần trả về 405, hãy thêm một handler bắt tất cả (catch-all) có đặt header
Allow.
Advertisement
Cách 5: Xử lý yêu cầu CORS preflight (OPTIONS)
Khi một trang web gọi API trên tên miền khác với dữ liệu JSON hoặc header tùy chỉnh, trước tiên trình duyệt sẽ gửi một yêu cầu OPTIONS preflight. Nếu API trả lời yêu cầu OPTIONS đó bằng mã 405, trình duyệt sẽ báo lỗi CORS và không bao giờ gửi yêu cầu thực, dù endpoint thực sự lẽ ra vẫn hoạt động.
Hãy để API trả lời OPTIONS cho các route đó bằng mã 204 hoặc 200 kèm đúng các header Access-Control-Allow-Methods và Access-Control-Allow-Headers. Hầu hết framework đều có middleware CORS làm việc này cho bạn. Ví dụ, chính API Tra Cứu DNS của DNS Robot trả lời preflight bằng mã 204 kèm các header CORS, nên trình duyệt có thể gọi nó từ bất kỳ trang web nào.
Lỗi 405 khác gì 400, 403, 404 và 501
| Mã | Ý nghĩa |
|---|---|
| 405 Method Not Allowed | URL có tồn tại, nhưng không dành cho phương thức này |
| 400 Bad Request | Bản thân yêu cầu bị sai định dạng |
| 403 Forbidden | Máy chủ hiểu yêu cầu nhưng không cho phép truy cập |
| 404 Not Found | Không có gì tồn tại tại URL này |
| 501 Not Implemented | Máy chủ không hỗ trợ phương thức này cho bất kỳ URL nào |
Hướng dẫn liên quan: 400 Bad Request, 403 Forbidden và 401 Unauthorized.
Kiểm tra xem một URL trả về những gì
Công cụ Kiểm Tra Header HTTP của DNS Robot hiển thị mã trạng thái và các header phản hồi của bất kỳ URL nào, giúp bạn xác nhận lỗi 405 và xem phần mềm máy chủ đứng sau nó.
Thử Kiểm Tra Header HTTPAdvertisement
Câu hỏi thường gặp
Nó có nghĩa là máy chủ nhận ra URL nhưng không chấp nhận phương thức HTTP được dùng, chẳng hạn một yêu cầu POST gửi đến trang chỉ cho phép GET. Phản hồi nên có header Allow liệt kê các phương thức mà URL đó chấp nhận.