为什么在简单的 API 控制器中不允许使用 DELETE 方法

ttd*_*tra 5 api rest yii2

基础工作非常好:

  • 获取索引 (/api/v1/pools)
  • 获取视图 (/api/v1/pools/1)
  • POST 创建 (/api/v1/pools)

但是当我尝试使用 DELETE delete (/api/v1/pools/1) 时,我收到以下消息:

不允许的方法

URL /api/v1/pools/1 不允许请求的方法 DELETE。

我什至将 checkAccess() 定义为一个空方法,但似乎没有任何帮助。

设置

控制器:

class PoolController extends \yii\rest\ActiveController
{
    public $modelClass = 'api\models\Pool';

    public function behaviors()
    {
        $behaviors = parent::behaviors();
        // authenticate by using an access token passed in the username authentication header
        $behaviors['authenticator'] = [
            'class' => HttpBasicAuth::className(),
        ];
        return $behaviors;
    }
}
Run Code Online (Sandbox Code Playgroud)

配置:

....
'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    //'enableStrictParsing' => true,
    'rules' => [
    [
        'class' => 'yii\rest\UrlRule', 
        'controller' => ['v1/pool'],
    ],
]
....
Run Code Online (Sandbox Code Playgroud)

请求和响应

卷曲删除请求

curl -X DELETE \
  https://###/api/v1/pools/1 \
  -H 'Authorization: Basic dHBDMEUxNWVscl8tNlF6OFVYSGV5V0NydVBwdEp5elM6' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache'
Run Code Online (Sandbox Code Playgroud)

卷曲响应

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method DELETE is not allowed for the URL         
/api/v1/pools/1.</p>
</body></html>
Run Code Online (Sandbox Code Playgroud)

wget 删除请求

wget --method DELETE 
  --header 'Content-Type: application/json'   
  --header 'Authorization: Basic dHBDMEUxNWVscl8tNlF6OFVYSGV5V0NydVBwdEp5elM6'   
  --header 'cache-control: no-cache'
  --output-document   - https://###/api/v1/pools/1
Run Code Online (Sandbox Code Playgroud)

wget DELETE 响应

HTTP request sent, awaiting response... 405 Method Not Allowed
2019-02-04 10:25:54 ERROR 405: Method Not Allowed.
Run Code Online (Sandbox Code Playgroud)

为清楚起见,下面显示了同一控制器中另一个操作(视图)的工作请求/响应:

卷曲 GET 请求

curl -X GET \
  https://###/api/v1/pools/1 \
  -H 'Authorization: Basic dHBDMEUxNWVscl8tNlF6OFVYSGV5V0NydVBwdEp5elM6' \
  -H 'cache-control: no-cache'
Run Code Online (Sandbox Code Playgroud)

卷曲 GET 响应

{"success":true,"data":{
    "id":1,
    "user_id":1,
    "name":"pool",
    ....
    "created_at":"2019-01-31 20:00:00"
}}
Run Code Online (Sandbox Code Playgroud)

进一步摆弄之后,我发现它总是会返回此消息,即使我故意在控制器或 api 主配置中引起内部错误。工作操作确实表明发生了内部错误。该请求甚至没有出现在调试器中,只有 GET、POST 和 HEAD 达到了那个程度。

ttd*_*tra 4

经过大量浪费时间后,我发现请求甚至没有出现在 api 调试器 (/api/debug/default/view) 中,并且消息存储库中的 grep 没有返回任何内容。这时我才开始期待服务员。

服务器运行 Apache/2.4.35 (Unix),在 /etc/httpd/conf/httpd/extra/httpd-directories.conf 中有一条规则阻止除 GET、HEAD 和 POST 请求之外的所有请求。我添加了 PUT、PATCH、DELETE 和 OPTIONS。

<Directory /home>
    AllowOverride All
    Options -MultiViews -Indexes +FollowSymLinks +IncludesNoExec +Includes
    AllowMethods GET HEAD POST PUT PATCH DELETE OPTIONS
</Directory>
Run Code Online (Sandbox Code Playgroud)

终于开始工作了。