记一次前端请求后端接口出现405的问题:
问题描述:
首先阐述http的405状态码,405的直接提示是method not allowed,即前端请求的方法不被后端接受。(如下图)
当时就纳闷了,我后端路由明明写的post方法,前端也是通过post的方法发起的请求,为什么会提示这个method不被允许。
后来仔细一看发现这个请求的request meshod,天啦撸,居然是option!!!
那么这个option是什么玩意,为什么会产生。
产生原因:
Http1.1共定义了9种请求方法,option就是其中的一种
GET | 请求指定的页面信息,并返回实体主体。 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
DELETE | 请求服务器删除指定的页面。 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
OPTIONS | 允许客户端查看服务器的性能。 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
option请求其实是一种浏览器自主发起的行为, 在满足以下情况的时候,在普通的get或post请求前,浏览器会自发的先发起一个option请求,检查服务端是否支持相关的方法或自定义信息,如果满足才会发起下一步的请求;
1、接口请求跨域,否则不会发起option请求;
2、有自定义的请求头信息或者请求头中的content-type是application/x-www-form-urlencoded,multipart/form-data,text/plain之外的格式。
我当时就是在做接口校验的时候让前端在head中添加了一个签名秘钥signature的自定义头信息,然后就出现了405的问题。
解决办法:
1、在服务端的路由请求部分新增option请求,允许option请求通过。
我这后端用的php的lumen,路由写法变化(当然也可修改路由类):
//原来写法
$app->post('/login','AdminController@login');
//新增option请求
$app->addRoute(['OPTIONS','POST'],'/login','AdminController@login');
2、对于所有的option请求,可以在cors中间件中对option请求统一返回200即可:
if ($request->getMethod() == "OPTIONS") {
return response()->json('ok', 200, [
//自定义内容
]);
}