原文
创建响应
字符串和数组
Laravel框架会自动将字符串转换为完整的HTTP相应:
1
2
3
| Route::get('/', function () {
return 'Hello World';
});
|
会自动将数组转换为JSON响应:
1
2
3
| Route::get('/', function () {
return [1, 2, 3];
});
|
响应对象
通过返回完整Response
实例,可以自定义相应的HTTP状态码和标头。
Response
应继承自Symfony\Component\HttpFoundation\Response
类
1
2
3
4
| Route::get('/home', function () {
return response('Hello World', 200)
->header('Content-Type', 'text/plain');
});
|
Eloquent模型和控制器
可以直接从路由和控制器返回Eloquent ORM模型和集合。会自动将模型和集合转换为JSON响应,同时遵循模型的隐藏属性:
1
2
3
4
5
| use App\Models\User;
Route::get('/user/{user}', function (User $user) {
return $user;
});
|
header
方法为响应添加一系列标头
1
2
3
4
| return response($content)
->header('Content-Type', $type)
->header('X-Header-One', 'Header Value')
->header('X-Header-Two', 'Header Value');
|
withHeaders
方法指定要添加到响应中的标头数组
1
2
3
4
5
6
| 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 标识符:
1
2
3
4
5
6
7
8
9
| Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
Route::get('/privacy', function () {
// ...
});
Route::get('/terms', function () {
// ...
});
});
|
将Cookie附加到响应
cookie
方法将cookie附加到Illuminate\Http\Response
实例
1
2
3
| return response('Hello World')->cookie(
'name', 'value', $minutes
);
|
还接受一些不太频繁使用的参数。通常,这些参数与 PHP 的原生 setcookie 方法的参数具有相同的目的和含义:
1
2
3
| return response('Hello World')->cookie(
'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);
|
如果想确保在发送响应时附带一个 cookie,但还没有该响应的实例,可以使用 Cookie facade 来将 cookie “队列化”,以便在发送响应时附加到响应上。
queue 方法接受创建 cookie 实例所需的参数。
这些 cookie 将在发送到浏览器之前附加到传出的响应上:
1
2
3
| use Illuminate\Support\Facades\Cookie;
Cookie::queue('name', 'value', $minutes);
|
生成Cookie实例
如果想生成一个可以稍后附加到响应实例的 Symfony\Component\HttpFoundation\Cookie
实例,可以使用全局 cookie 辅助函数。
除非该 cookie 被附加到响应实例,否则它不会发送回客户端:
1
2
3
| $cookie = cookie('name', 'value', $minutes);
return response('Hello World')->cookie($cookie);
|
提前过期Cookie
可以通过传出响应 withoutCookie
的方法使 cookie 过期来删除 cookie:
1
| return response('Hello World')->withoutCookie('name');
|
如果还没有传出响应的实例,则可以使用 Cookie
Facade expire
的方法使 cookie 过期:
1
| Cookie::expire('name');
|
Cookie加密
默认情况下,由于 Illuminate\Cookie\Middleware\EncryptCookies
中间件的存在,Laravel 生成的所有 cookie 都经过加密和签名,因此客户端无法修改或读取它们。
如果想禁用应用程序生成的 cookie 子集的加密,可以使用应用程序 bootstrap/app.php
文件中的方法 encryptCookies
:
1
2
3
4
5
| ->withMiddleware(function (Middleware $middleware) {
$middleware->encryptCookies(except: [
'cookie_name',
]);
})
|
重定向
重定向响应是 Illuminate\Http\RedirectResponse
类的实例,包含将用户重定向到另一个 URL 所需的正确标头。有几种方法可以生成 RedirectResponse
实例。最简单的方法是使用全局 redirect
帮助程序:
1
2
3
| Route::get('/dashboard', function () {
return redirect('home/dashboard');
});
|
有时,需要将用户重定向到其以前的位置,例如当提交的表单无效时。可以使用全局 back
帮助程序函数来执行此操作。由于此功能利用会话,因此请确保调用函数的 back
路由使用 web
中间件组:
1
2
3
4
5
| Route::post('/user/profile', function () {
// Validate the request...
return back()->withInput();
});
|
重定向到命名路由
当调用不带参数的 redirect
帮助程序时,将返回一个实例 Illuminate\Routing\Redirector
,允许调用 Redirector
实例上的任何方法。
例如,要生成 RedirectResponse
到命名路由,可以使用以下 route
方法:
1
| return redirect()->route('login');
|
如果路由具有参数,则可以将它们作为第二个参数传递给 route
方法:
1
2
3
| // For a route with the following URI: /profile/{id}
return redirect()->route('profile', ['id' => 1]);
|
通过Eloquent模型填充参数
如果要重定向到具有“ID”参数的路由,该路由是从 Eloquent 模型填充的,则可以传递模型本身。将自动提取 ID:
1
2
3
| // For a route with the following URI: /profile/{id}
return redirect()->route('profile', [$user]);
|
如果要自定义放置在路由参数中的值,可以在路由参数定义 ( /profile/{id:slug}
) 中指定列,也可以在 Eloquent 模型上重写该 getRouteKey
方法:
1
2
3
4
5
6
7
| /**
* Get the value of the model's route key.
*/
public function getRouteKey(): mixed
{
return $this->slug;
}
|
重定向至控制器操作
还可以生成指向控制器操作的重定向。为此,请将控制器和操作名称传递给 action
方法:
1
2
3
| use App\Http\Controllers\UserController;
return redirect()->action([UserController::class, 'index']);
|
如果控制器路由需要参数,则可以将它们作为第二个参数传递给 action
方法:
1
2
3
| return redirect()->action(
[UserController::class, 'profile'], ['id' => 1]
);
|
重定向到外部域
可以通过调用该 away
方法重定向到应用程序外的域。
该方法将 RedirectResponse
创建一个无需任何其他 URL 编码、验证或验证的方法:
1
| return redirect()->away('https://www.google.com');
|
使用闪存的会话数量重定向
重定向到新 URL 和将数据刷入会话通常同时完成。
通常,这是在成功执行操作后,当向会话刷新成功消息时完成的。
为方便起见,可以创建一个 RedirectResponse
实例,并在单个流畅的方法链中将数据闪存到会话中:
1
2
3
4
5
| Route::post('/user/profile', function () {
// ...
return redirect('dashboard')->with('status', 'Profile updated!');
});
|
重定向用户后,可以显示会话中闪烁的消息。例如,使用 Blade 语法:
1
2
3
4
5
| @if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
|
使用输入重定向
在将用户重定向到新位置之前,可以使用 RedirectResponse
实例提供 withInput
的方法将当前请求的输入数据刷新到会话。
如果用户遇到验证错误,通常会执行此操作。
将输入切换到会话后,可以在下一次请求重新填充表单时轻松检索它:
1
| return back()->withInput();
|
其他响应类型
View 响应
1
2
3
| return response()
->view('hello', $data, 200)
->header('Content-Type', $type);
|
如果不需要传递自定义 HTTP 状态码或自定义标头,则可以使用全局 view
帮助程序函数。
JSON 响应
该 json
方法会自动将 Content-Type
标头设置为 application/json
,并使用 json_encode
PHP 函数将给定的数组转换为 JSON:
1
2
3
4
| return response()->json([
'name' => 'Abigail',
'state' => 'CA',
]);
|
如果要创建 JSONP 响应,可以将该 json
方法与以下 withCallback
方法结合使用
1
2
3
| return response()
->json(['name' => 'Abigail', 'state' => 'CA'])
->withCallback($request->input('callback'));
|
文件下载
该 download
方法可用于生成响应,强制用户的浏览器在给定路径下载文件。
该 download
方法接受文件名作为该方法的第二个参数,该参数将确定下载文件的用户看到的文件名。
最后,可以将 HTTP 标头数组作为第三个参数传递给该方法:
1
2
3
| return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
|
流下载
该 streamDownload
方法可用于将给定操作的字符串响应转换为可下载的响应,而无需将操作的内容写入磁盘。
此方法接受回调、文件名和可选的标头数组作为其参数:
1
2
3
4
5
6
7
| use App\Services\GitHub;
return response()->streamDownload(function () {
echo GitHub::api('repo')
->contents()
->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');
|
文件响应
该 file
方法可用于直接在用户的浏览器中显示文件(如图像或 PDF),而不是启动下载。
此方法接受文件的绝对路径作为其第一个参数,并接受标头数组作为其第二个参数:
1
2
3
| return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
|
响应宏
如果要定义可在各种路由和控制器中重复使用的自定义响应,则可以在 Response
外观上使用该 macro
方法。
通常,应从应用程序的服务提供商之一(如 App\Providers\AppServiceProvider
服务提供商) boot
的方法调用此方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <?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
帮助程序调用宏名称时,将执行宏的闭包:
1
| return response()->caps('foo');
|