HTTP 响应

创建响应

字符串和数组

所有路由和控制器都应返回响应以发送回用户的浏览器。 Laravel 提供了几种不同的方式来返回响应。最基本的响应是从路由或控制器返回一个字符串。该框架会自动将字符串转换为完整的 HTTP 响应:

Route::get('/', function () {
    return 'Hello World';
});

除了从路由和控制器返回字符串外,您还可以返回数组。该框架会自动将数组转换为 JSON 响应:

Route::get('/', function () {
    return [1, 2, 3];
});

Note
你知道吗你也可以返回雄辩的收藏 从你的路线或控制器?它们将自动转换为 JSON。试一试!

响应对象

通常,您不会只是从路由操作中返回简单的字符串或数组。相反,您将满载而归Illuminate\Http\Response 实例或views.

返回一个完整的Response instance 允许您自定义响应的 HTTP 状态代码和标头。 AResponse 实例继承自Symfony\Component\HttpFoundation\Response 类,它提供了多种构建 HTTP 响应的方法:

Route::get('/home', function () {
    return response('Hello World', 200)
                  ->header('Content-Type', 'text/plain');
});

雄辩的模型和集合

你也可以返回雄辩的ORM 直接来自您的路线和控制器的模型和集合。当你这样做时,Laravel 会自动将模型和集合转换为 JSON 响应,同时尊重模型的隐藏属性:

use App\Models\User;

Route::get('/user/{user}', function (User $user) {
    return $user;
});

将标题附加到响应

请记住,大多数响应方法都是可链接的,从而可以流畅地构建响应实例。例如,您可以使用header 在将响应发送回用户之前向响应添加一系列标头的方法:

return response($content)
            ->header('Content-Type', $type)
            ->header('X-Header-One', 'Header Value')
            ->header('X-Header-Two', 'Header Value');

或者,您可以使用withHeaders 指定要添加到响应中的标头数组的方法:

return response($content)
            ->withHeaders([
                'Content-Type' => $type,
                'X-Header-One' => 'Header Value',
                'X-Header-Two' => 'Header Value',
            ]);

缓存控制中间件

Laravel 包括一个cache.headers 中间件,可用于快速设置Cache-Control 一组路由的标题。指令应使用与相应缓存控制指令等效的“蛇形”提供,并应以分号分隔。如果etag 在指令列表中指定,响应内容的 MD5 哈希将自动设置为 ETag 标识符:

Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
    Route::get('/privacy', function () {
        // ...
    });

    Route::get('/terms', function () {
        // ...
    });
});

将 Cookie 附加到响应

您可以将 cookie 附加到传出的Illuminate\Http\Response 实例使用cookie 方法。您应该将 cookie 的名称、值和分钟数传递给此方法:

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

cookie 方法还接受一些使用频率较低的参数。通常,这些参数与提供给 PHP 原生的参数具有相同的目的和含义。setcookie 方法:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

如果您想确保 cookie 与传出响应一起发送,但您还没有该响应的实例,您可以使用Cookie 在发送响应时“排队”cookie 以附加到响应的外观。这queue 方法接受创建 cookie 实例所需的参数。这些 cookie 将在发送到浏览器之前附加到传出响应:

use Illuminate\Support\Facades\Cookie;

Cookie::queue('name', 'value', $minutes);

生成 Cookie 实例

如果你想生成一个Symfony\Component\HttpFoundation\Cookie 稍后可以附加到响应实例的实例,您可以使用全局cookie 帮手。除非附加到响应实例,否则此 cookie 不会被发送回客户端:

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

提前过期 Cookie

您可以通过使 cookie 过期来删除 cookiewithoutCookie 传出响应的方法:

return response('Hello World')->withoutCookie('name');

如果您还没有传出响应的实例,您可以使用Cookie门面的expire 使cookie过期的方法:

Cookie::expire('name');

饼干和加密

默认情况下,Laravel 生成的所有 cookie 都经过加密和签名,因此客户端无法修改或读取它们。如果您想对您的应用程序生成的一部分 cookie 禁用加密,您可以使用$except 的财产App\Http\Middleware\EncryptCookies 中间件,它位于app/Http/Middleware 目录:

/**
 * The names of the cookies that should not be encrypted.
 *
 * @var array
 */
protected $except = [
    'cookie_name',
];

Redirects

重定向响应是Illuminate\Http\RedirectResponse 类,并包含将用户重定向到另一个 URL 所需的正确标头。有几种方法可以生成一个RedirectResponse 实例。最简单的方法是使用全局redirect 帮手:

Route::get('/dashboard', function () {
    return redirect('home/dashboard');
});

有时您可能希望将用户重定向到他们以前的位置,例如当提交的表单无效时。您可以使用全局back 辅助功能。由于此功能利用了session,确保调用的路由back 函数正在使用web 中间件组:

Route::post('/user/profile', function () {
    // Validate the request...

    return back()->withInput();
});

重定向到命名路由

当你打电话给redirect 没有参数的助手,一个实例Illuminate\Routing\Redirector 被返回,允许你调用任何方法Redirector 实例。例如,生成一个RedirectResponse 到命名路线,您可以使用route 方法:

return redirect()->route('login');

如果你的路由有参数,你可以将它们作为第二个参数传递给route 方法:

// For a route with the following URI: /profile/{id}

return redirect()->route('profile', ['id' => 1]);

通过 Eloquent 模型填充参数

如果您要重定向到带有从 Eloquent 模型填充的“ID”参数的路由,您可以传递模型本身。 ID 将自动提取:

// For a route with the following URI: /profile/{id}

return redirect()->route('profile', [$user]);

如果您想自定义放置在路由参数中的值,您可以在路由参数定义中指定列 (/profile/{id:slug}) 或者你可以覆盖getRouteKey Eloquent 模型上的方法:

/**
 * Get the value of the model's route key.
 */
public function getRouteKey(): mixed
{
    return $this->slug;
}

重定向到控制器操作

您还可以生成重定向到控制器动作.为此,将控制器和操作名称传递给action 方法:

use App\Http\Controllers\UserController;

return redirect()->action([UserController::class, 'index']);

如果你的控制器路由需要参数,你可以将它们作为第二个参数传递给action 方法:

return redirect()->action(
    [UserController::class, 'profile'], ['id' => 1]
);

重定向到外部域

有时您可能需要重定向到应用程序之外的域。您可以通过致电away 方法,它创建一个RedirectResponse 无需任何额外的 URL 编码、验证或验证:

return redirect()->away('https://www.google.com');

使用闪现会话数据重定向

重定向到一个新的 URL 和将数据闪烁到会话 通常是同时进行的。通常,这是在您向会话闪现成功消息时成功执行操作后完成的。为了方便起见,您可以创建一个RedirectResponse 在单个流畅的方法链中将实例和闪存数据发送到会话:

Route::post('/user/profile', function () {
    // ...

    return redirect('dashboard')->with('status', 'Profile updated!');
});

用户被重定向后,您可以显示来自session.例如,使用刀片语法:

@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

使用输入重定向

您可以使用withInput 提供的方法RedirectResponse 在将用户重定向到新位置之前将当前请求的输入数据闪存到会话的实例。如果用户遇到验证错误,通常会这样做。一旦输入被闪现到会话中,你可以很容易地取回它 在下一个重新填充表单的请求期间:

return back()->withInput();

其他响应类型

response helper 可用于生成其他类型的响应实例。当。。。的时候response helper 在没有参数的情况下被调用,一个实现Illuminate\Contracts\Routing\ResponseFactory contract 被退回。该合约提供了几种有用的方法来生成响应。

查看回复

如果您需要控制响应的状态和标头,但还需要返回一个view 作为响应的内容,您应该使用view 方法:

return response()
            ->view('hello', $data, 200)
            ->header('Content-Type', $type);

当然,如果您不需要传递自定义 HTTP 状态代码或自定义标头,您可以使用全局view 辅助功能。

JSON 响应

json 方法将自动设置Content-Type 标头到application/json,以及使用json_encode PHP函数:

return response()->json([
    'name' => 'Abigail',
    'state' => 'CA',
]);

如果你想创建一个 JSONP 响应,你可以使用json 方法结合withCallback 方法:

return response()
            ->json(['name' => 'Abigail', 'state' => 'CA'])
            ->withCallback($request->input('callback'));

文件下载

download 方法可用于生成一个响应,强制用户的浏览器在给定路径下载文件。这download 方法接受一个文件名作为该方法的第二个参数,它将确定用户下载文件时看到的文件名。最后,您可以将 HTTP 标头数组作为第三个参数传递给该方法:

return response()->download($pathToFile);

return response()->download($pathToFile, $name, $headers);

Warning
管理文件下载的 Symfony HttpFoundation 要求下载的文件具有 ASCII 文件名。

流式下载

有时您可能希望将给定操作的字符串响应转换为可下载的响应,而不必将操作的内容写入磁盘。您可以使用streamDownload 这种情况下的方法。此方法接受回调、文件名和可选的标题数组作为其参数:

use App\Services\GitHub;

return response()->streamDownload(function () {
    echo GitHub::api('repo')
                ->contents()
                ->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');

文件回复

file 方法可用于直接在用户的浏览器中显示文件,例如图像或 PDF,而不是启动下载。此方法接受文件路径作为其第一个参数,并接受标题数组作为其第二个参数:

return response()->file($pathToFile);

return response()->file($pathToFile, $headers);

响应宏

如果您想定义一个可以在各种路由和控制器中重复使用的自定义响应,您可以使用macro 上的方法Response 正面。通常,您应该从boot 您的应用程序之一的方法服务供应商, 如那个App\Providers\AppServiceProvider 服务提供者:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Response::macro('caps', function (string $value) {
            return Response::make(strtoupper($value));
        });
    }
}

macro 函数接受一个名字作为它的第一个参数,一个闭包作为它的第二个参数。宏的闭包将在调用宏名称时执行ResponseFactory 实施或response 帮手:

return response()->caps('foo');
豫ICP备18041297号-2