【问题标题】:Laravel 8 misbehaves on trailing slashLaravel 8 在斜杠上行为不端
【发布时间】:2021-10-16 11:32:06
【问题描述】:

使用带有斜杠的 API 时出现问题。

路线

Route::post('user/register','UserController@register');

当我从邮递员/网站调用这条路线 POST 时,它工作正常,但我从移动设备调用这条路线并带有如下斜杠。

user/register/

默认情况下,Laravel 会删除尾部斜杠,但在我转储请求方法时将请求设为 GET

$method = $_SERVER['REQUEST_METHOD'];
$json = json_encode(['response' => $method], true);

result  -> "{response : 'GET'}"

而且我无法获取请求正文。

注意:我尝试了很多解决方案,但没有找到任何解决方案,而且我无法从移动端删除或更新路由调用,所以我必须在服务器端处理它。

【问题讨论】:

  • Route::post('user/register','UserController@register'); 路由是显示表单还是保存数据?
  • 这是一个 api 路由,所以它可以保存数据和响应
  • 当你注册为“post”时,你不能只在手机上“获取”一条路线
  • 他们实际上是在发出一个post 请求,但带有一个斜杠,laravel 在该斜杠上删除了 user/register/ 而不是 user/register 之类的斜杠,并将其视为 get 请求

标签: laravel api .htaccess laravel-8 trailing-slash


【解决方案1】:

您可以发布您的路线文件吗?他们可能有一个小错误。我用一个非常简单的代码尝试了它,一切都按预期工作:

// routes/api.php
<?php

Route::post('/foo', function(Request $request) {
    return new JsonResponse('post');
});

Route::get('/foo', function(Request $request) {
    return new JsonResponse('get');
});

如果我使用 Postman 调用带有或不带有斜杠的 GET API,则返回“get”。如果我使用 Postman 调用带有或不带有斜杠的 POST API,则返回“post”。

问题也可能是由于您的移动应用配置不正确,而不是 Laravel 中的问题。

【讨论】:

  • 他们使用xxx-www-urlencoded-form 发送数据,所以当他们调用带有斜杠/ 的api 时,laravel 默认会删除斜杠,而我收到的方法操作是与空正文一样。
【解决方案2】:

当 Laravel 检测到尾部斜杠时,它会返回 301 重定向到“无尾部斜杠”版本。重定向的请求始终是“GET”,因此您将无法获得 POST 结果。

防止这种情况的唯一方法(假设您使用的是 Apache)是转到您的 .htaccess 文件(应该在您的 laravel 安装的公共目录中)并删除以下内容:

# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]

现在带有斜杠的 URL 将不再被重定向。

编辑:如果您想阻止仅某些 URI 的重定向,而不是删除这些行,您需要指定更严格的条件。例如,要停止仅重定向包含“客户”的链接,您可以这样做:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !customer
RewriteRule ^ %1 [L,R=301]

只有不包含“客户”的链接才会被重定向。

【讨论】:

  • 我可以检查这个特定的路由前缀吗?就像如果路线有customer/ 然后user/register 然后不要检查尾随斜杠,否则按原样工作。
【解决方案3】:

正如你所说,这是一条api 路由,你应该这样称呼它:

api/user/register

如果您不能从移动设备更改它,您应该通过这种方式从api 路由中删除默认的api 前缀:

app\Providers\RouteServiceProvider 中将Route::prefix('api') 更改为Route::prefix('')

【讨论】:

  • 我上面已经提到,我不能从移动端更改路由,所以我必须在服务器上处理它
  • 我有一个 api 的自定义路由文件,所以它没有使用 api 前缀
猜你喜欢
  • 1970-01-01
  • 2016-03-30
  • 2023-03-09
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 2017-06-12
相关资源
最近更新 更多