request::isoptions() 是识别 options 请求的正确方式,因其校验 cors 预检头、兼容代理改写、语义化且可扩展;param() 总为空因 options 无请求体且不触发 get/post 解析,应通过 header 传参。

Request::isOptions() 是识别 OPTIONS 请求的正确方式,不是靠 method() 字符串比对,也不是用 param() 或 post() 去读数据——因为 OPTIONS 请求通常不带请求体,也不走表单解析流程。
为什么 isOptions() 必须用,不能用 method() == 'OPTIONS'
虽然 Request::method() 确实返回字符串 'OPTIONS',但直接字符串判断有隐患:
- 某些代理或 CDN 可能改写
REQUEST_METHOD,而isOptions()内部会额外校验HTTP_ACCESS_CONTROL_REQUEST_METHOD等 CORS 预检头,更健壮 - 框架在中间件链中可能已对 method 做过标准化(比如把大写转小写再还原),
method()返回值未必 100% 可信 -
isOptions()是语义化判断,后续升级若增加预检逻辑(如检查 Origin 头是否合法),它会自动覆盖,你不用改代码
OPTIONS 请求里 request()->param() 为什么总是空
因为 param() 默认合并 GET、POST、ROUTE、PUT/DELETE 解析数据,但 OPTIONS 请求:
- 不携带
php://input内容(CORS 预检不发 body) - 不触发
$_POST或$_GET自动填充(浏览器不附带 query string) -
param()底层调用input()时,对 OPTIONS 会跳过所有解析分支,直接返回空数组
所以别写 $request->param('token') 试图从 OPTIONS 里取参数——它永远是 null 或空数组。真要传参,得走 header,比如 Authorization: Bearer xxx,然后用 $request->header('authorization') 拿。
实际处理 OPTIONS 预检的推荐写法
典型场景是为跨域接口加预检响应。不要在控制器方法里写复杂逻辑,而是用中间件或路由闭包拦截:
// routes/api.php
Route::options('api/user', function () {
return response('', 204)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
});
或者在控制器方法开头快速判别并退出:
public function update(Request $request)
{
if ($request->isOptions()) {
return response('', 204)->header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
}
// 后续正常处理 PUT 逻辑
}
注意:如果用了全局 CORS 中间件,就别在每个方法里重复判断——中间件应统一处理 isOptions() 并提前返回,避免进到业务逻辑层。
真正容易被忽略的是:OPTIONS 请求不会触发模型验证、不会走参数绑定、也不会执行任何业务逻辑——它只是“探路”。别把它当成普通接口去设计参数规则或日志记录,否则会发现日志里一堆空参数和 204 响应,却查不到问题在哪。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











