最直接可靠的方式是读取 $_SERVER['REQUEST_METHOD'](PHP)、req.method(Express)、request.method(Django),三者均返回标准HTTP方法名,需注意大小写处理与数据载体无关。

PHP 中用 $_SERVER['REQUEST_METHOD'] 判断请求类型
最直接、最可靠的方式就是读取 $_SERVER['REQUEST_METHOD'],它返回的是标准 HTTP 方法名,大小写固定为大写。
常见错误是误用 $_POST 或 $_GET 数组是否为空来判断——比如表单提交空数据时 $_POST 为空但仍是 POST 请求;或者 URL 带参数的 POST 请求里 $_GET 不为空,但请求类型仍是 POST。
-
$_SERVER['REQUEST_METHOD'] === 'GET'表示 GET 请求(包括地址栏直接访问、链接跳转、图片 script 标签加载等) -
$_SERVER['REQUEST_METHOD'] === 'POST'表示 POST 请求(表单提交、AJAXfetch()/XMLHttpRequest指定 method: 'POST') - 注意:
PUT、DELETE等方法也可能出现,尤其在 RESTful 接口里,不能只默认非 GET 即 POST
Node.js Express 中用 req.method 获取请求方法
Express 的 req 对象上,req.method 是原生的字符串值,和 $_SERVER['REQUEST_METHOD'] 语义一致,但大小写不保证统一——实际运行中通常是大写,但规范允许小写,所以比较时建议转大写。
容易踩的坑是直接写 if (req.method === 'post'),结果在某些代理或测试工具下失败。另外,Express 不会自动解析 PUT / PATCH 的请求体,需配 express.json() 和 express.urlencoded() 中间件,否则 req.body 为空,但 req.method 仍正确。
- 安全写法:
req.method.toUpperCase() === 'POST' - 不要依赖
req.body是否有值来反推方法——GET 请求也能通过fetch带 body,只是不符合惯例 - 如果用了
app.use(express.methodOverride()),还要注意是否启用了_method参数伪装,此时req.method是真实方法,而伪装逻辑在中间件层处理
前端 JavaScript 无法直接读取当前页面的请求类型
浏览器环境里,JavaScript 运行在响应已返回之后,没有 API 能获取“当前页面是用什么方法加载的”。所谓“当前请求”,对前端来说并不存在上下文意义上的“当前”。
有人试图从 document.referrer 或 history.state 推断,但完全不可靠——来源可能是手动输入、书签、HTTP 重定向(302),甚至跨域 iframe。唯一可控的做法是后端把方法信息显式传给前端。
- 服务端渲染时注入:
<script>window._requestMethod = '<code>GET</script>' - API 返回字段里带
method字段(仅限 AJAX 场景) - 不要尝试解析
performance.getEntriesByType('navigation')[0].type——它返回的是reload/back_forward/navigate,不是 HTTP 方法
Django 中用 request.method 属性判断
Django 的 request.method 是字符串属性,恒为大写,和 Express 不同,它不依赖中间件就能稳定工作,因为框架在请求解析早期就已标准化。
一个典型误区是混淆 request.method 和 request.META['REQUEST_METHOD']——后者是原始 WSGI 环境变量,理论上可能被中间件篡改,而前者是 Django 封装后的可信值。
- 正确用法:
if request.method == 'POST': - 不要用
request.POST是否为空判断,因为 POST 请求可能没表单数据(如 JSON API) - CSRF 验证只对 POST/PUT/PATCH/DELETE 默认启用,但判断依据仍是
request.method,不是有没有request.POST
判断请求类型这事本身不难,难的是意识到「方法」和「数据载体」是两回事——POST 可以没 body,GET 可以带 query 但仍是 GET。最容易被忽略的,是前后端职责错位:前端不该猜,后端不该省略显式传递。










