首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >浏览器访问Laravel时的HTTP状态代码419

浏览器访问Laravel时的HTTP状态代码419
EN

Stack Overflow用户
提问于 2022-03-31 19:20:27
回答 2查看 661关注 0票数 1

我无法通过浏览器访问本地主机上的laravel路由(脚本/控制台/开发工具)。我总是收到HTTP 419 (页过期)状态错误。有趣的是,我可以通过邮递员成功地访问api。

路线不在所有的“奥斯:圣殿”集团之外,所以这不应该是失败的原因。正因为如此,我还认为会话和会话配置不可能是原因,对吗?

代码语言:javascript
运行
复制
// routes/api.php
Route::post('/test', function() {
    return "Hello World @ POST";
}); // => HTTP 419

Route::get('/test', function() {
    return "Hello World @ GET";
}); // => HTTP 200

我从xsrf检查中排除了路径,以排除此错误原因:

代码语言:javascript
运行
复制
// VerifyCsrfToken.php
protected $except = [
    'api/test',
];

我在firefox控制台中运行的脚本:

代码语言:javascript
运行
复制
await fetch("http://localhost:8000/api/test", {
    "method": "POST"
});

HTTP请求firefox发送到本地主机:

代码语言:javascript
运行
复制
POST /api/test HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:8000/
Origin: http://127.0.0.1:8000
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Content-Length: 0

如何使api在浏览器中运行?

EDIT#1

app/http/kernel.php

代码语言:javascript
运行
复制
<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
        
        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array<string, class-string|string>
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}
EN

回答 2

Stack Overflow用户

发布于 2022-11-23 23:10:30

原因是App\Http\Middleware\VerifyCsrfToken的父类是Illuminate\Foundation\Http\Middleware\VerifyCsrfToken,它的句柄方法有以下代码:

代码语言:javascript
运行
复制
public function handle($request, Closure $next)
    {
        if (
            $this->isReading($request) ||
            $this->runningUnitTests() ||
            $this->inExceptArray($request) ||
            $this->tokensMatch($request)
        ) {
            return tap($next($request), function ($response) use ($request) {
                if ($this->shouldAddXsrfTokenCookie()) {
                    $this->addCookieToResponse($request, $response);
                }
            });
        }

        throw new TokenMismatchException('CSRF token mismatch.');
    }

对那个大型if的第一个检查是$this->isReading($request)。该方法负责检查正在使用的请求方法,如果您看到它的实现:

代码语言:javascript
运行
复制
/**
     * Determine if the HTTP request uses a ‘read’ verb.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function isReading($request)
    {
        return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
    }

所以我想不需要更多的话了。

在这里,您应该问问自己,为什么他们忽略了POST方法。

如果您对此过于肯定,可以在App\Http\Middleware\VerifyCsrfToken中重写该方法

代码语言:javascript
运行
复制
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array<int, string>
     */
    protected $except = [
        //
    ];

    protected function isReading($request): bool
    {
        return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS', 'POST']);
    }
}

你可以开始读

票数 0
EN

Stack Overflow用户

发布于 2022-03-31 19:46:48

  1. 从浏览器url post路由访问将无法工作。除非你通过表格
代码语言:javascript
运行
复制
<form action="/api/test" method="POST">
<button type="submit">Submit</button>
</form>
  • 可能通过一个按钮/链接将提交隐藏在场景后面的表单连接起来。

换句话说,从我所看到的你应该能够:

  • GET /api/test (浏览器网址、浏览器表单和邮递员)
  • POST /api/test (浏览器表单,邮递员)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71698050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档