1. 创建响应

1.1 字符串&数组

所有路由和控制器处理完业务逻辑之后都会返回一个发送到用户浏览器的响应,最基本的响应就是从路由或者控制器返回一个简单的字符串,框架会自动将这个字符串转换为一个完整的HTTP响应:

  1. <?pho
  2. Route::get('/', function () {
  3. return 'Hello World';
  4. });

测试结果如下:
image.png

如果是返回的数组,那么框架将自动把数组装换一个JSON响应

  1. <?php
  2. Route::get('/', function () {
  3. return [1, 2, 3];
  4. });

测试结果如下:我的前端助手将数据格式调整为JSON,说明返回的就是JSON
image.png

1.2 Response 对象

通常,我们并不是从路由动作简单的安徽字符串和数组,大多数情况下,都会返回一个完整的 Illuminate\Http\Response 实例或者视图。如果是返回一个完整的 response 实例的话,实例允许你自定义响应的HTTP状态码和响应头信息。Response 实例 继承自 Symfony\Component\HttpFoundation\Response 类, 该类提供了各种构建 HTTP 响应的方法:

  1. <?php
  2. Route::get('home', function () {
  3. return response('Hello World', 200)
  4. ->header('Content-Type', 'text/plain');
  5. });

1.3 添加响应头的两种常见方式

  1. <?php
  2. # 添加响应头
  3. Route::get('home', function () {
  4. $content = '这就是一句话而已';
  5. $type = 'text/html';
  6. return response($content)
  7. ->header('Content-Type', $type)
  8. ->header('X-Header-One', 'Header Value')
  9. ->header('X-Header-Two', 'Header Value');
  10. });
  11. # 添加响应头的另外一种方式
  12. Route::get('home', function () {
  13. $content = '这就是一句话而已';
  14. $type = 'text/html';
  15. return response($content)
  16. ->withHeaders([
  17. 'Content-Type' => $type,
  18. 'X-Header-One' => 'Header Value',
  19. 'X-Header-Two' => 'Header Value',
  20. ]);
  21. });

1.4 缓存控制中间件

Laravel 内置了一个 cache.headers 中间件,可以用来快速地为路由组设置 Cache-Control 头信息。如果在指令集中声明了 etag,Laravel 会自动将 ETag 标识符设置为响应内容的 MD5 哈希值:

  1. <?php
  2. # 缓存控制中间件
  3. Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
  4. Route::get('privacy', function () {
  5. return 'privacy';
  6. });
  7. Route::get('terms', function () {
  8. return 'terms';
  9. });
  10. });

1.5 添加 Cookies 到响应

你可以使用响应上的 cookie 方法轻松地将为响应增加 Cookies。例如,你可以像这样使用 cookie 方法生成一个 cookie 并轻松地将其附加到响应上:

  1. <?php
  2. /**
  3. * 添加 Cookies 到响应
  4. */
  5. Route::get('cookie', function () {
  6. $content = '我要添加cookie了';
  7. $type = 'text/plain';
  8. $minutes = 30;
  9. return response($content)
  10. ->header('Content-Type', $type)
  11. ->cookie('name', 'value', $minutes);
  12. });

cookie 方法还接受一些不太频繁使用的参数。通常,这些参数与原生 PHP 的 setcookie 方法的参数有着相同的目的和含义:

  1. <?php
  2. ->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)

或者,你可以使用 Cookie facade 「队列」, Cookie 以附加到应用程序的传出响应。 queue 方法接受一个 Cookie 实例或创建 Cookie 实例所需的参数。 这些 cookie 在发送到浏览器之前会附加到传出响应中:

  1. <?php
  2. Cookie::queue(Cookie::make('name', 'value', $minutes));
  3. Cookie::queue('name', 'value', $minutes);

默认情况下,Laravel 生成的所有 Cookie 都是经过加密和签名,因此不能被客户端修改或读取。 如果你想要应用程序生成的部分 Cookie 不被加密,那么可以使用在 app/Http/Middleware 目录中 App\Http\Middleware\EncryptCookies 中间件的 $except 属性:

  1. <?php
  2. /**
  3. * The names of the cookies that should not be encrypted.
  4. *
  5. * @var array
  6. */
  7. protected $except = [
  8. 'cookie_name',
  9. ];

2. 重定向

重定向响应是 Illuminate\Http\RedirectResponse 类的实例,并且包含用户需要重定向至另一个 URL 所需的头信息。Laravel 提供了几种方法用于生成 RedirectResponse 实例。其中最简单的方法是

2.1 辅助函数 redirect

demo

  1. <?php
  2. # 关于重定向的一种最简单的使用方式
  3. Route::get('dashboard', function () {
  4. return redirect('home/dashboard');
  5. });
  6. # 被定向的路由
  7. Route::get('home/dashboard', function () {
  8. return 'Hi home/dashboard ';
  9. });

测试结果
image.png

有时候你可能希望将用户重定向到之前的位置,比如提交的表单无效时。这时你可以使用全局辅助函数 back 来执行此操作。由于这个功能利用了 会话控制,请确保调用 back 函数的路由使用 web 中间件组或所有 Session 中间件:

  1. <?php
  2. Route::post('user/profile', function () {
  3. // 验证请求
  4. return back()->withInput();
  5. });

2.2 重定向到命名路由

如果调用不带参数的辅助函数 redirect 时,会返回 Illuminate\Routing\Redirector 实例。这个实例允许你调用 Redirector 上的任何方法。例如为命名路由生成 RedirectResponse,可以使用 route 方法

  1. <?php
  2. // 对于具有该URI的路由: profile/{id}
  3. return redirect()->route('profile', ['id' => 1]);

如果路由中有参数,可以将其作为第二个参数传递到 route 方法:

  1. <?php
  2. // 对于具有该URI的路由: profile/{id}
  3. return redirect()->route('profile', ['id' => 1]);

2.3 通过 Eloquent 模型填充参数

2.4 重定向到控制器行为

还可以生成到 controller action 的重定向。要达到这个目的,只要把 控制器 和 action 的名称传递给 action 方法。记住,不需要传递控制器的全部命名空间,Laravel 的 RouteServiceProvider 会自动将其设置为基本控制器的命名空间:

  1. <?php
  2. return redirect()->action('HomeController@index');

如果控制器路由需要参数,可以将其作为 action 方法的第二个参数:

  1. <?php
  2. return redirect()->action(
  3. 'UserController@profile', ['id' => 1]
  4. );

测试,这里有一个经常会出现的错误,我这里记录一下

  1. <?php
  2. # 路由重定向到控制器行为
  3. Route::get('way2', function () {
  4. return redirect()->action('my\Response@fun2');
  5. });

然后直接访问会报错,找不到这个方法,因为laravel是强制路由的。
image.png

正确的姿势

  1. <?php
  2. # 路由重定向到控制器行为
  3. Route::get('way2', function () {
  4. return redirect()->action('my\Response@fun2');
  5. });
  6. # laravel 中是强制路由,方法必须经过路由
  7. Route::get('way2', 'my\Response@fun2');

然后测试,OK了
image.png

路由重定向到控制器行为,如果携带参数呢。例子如下

  1. <?php
  2. # 路由绑定到控制器行为,携带多个参数
  3. Route::get('way3/{id}/{name}/{age}', function ($id, $name, $age) {
  4. return redirect()->action('my\Response@fun3', [
  5. 'id' => $id,
  6. 'name' => $name,
  7. 'age' => $age,
  8. ]);
  9. });
  10. # 注册路由
  11. Route::get('way3/{id}/{name}/{age}', 'my\Response@fun3');

测试效果 : 路径有问题,这里先不管,发现使用action,就像是废话一样 … … 不如不用
image.png

2.5 重定向到外部域名

有时候你需要重定向到应用外的域名。调用 away 方法可以达到此目的,它会创建一个不带有任何额外的 URL 编码、有效性校验和检查的 RedirectResponse 实例:

  1. <?php
  2. return redirect()->away('https://www.google.com');

2.6 重定向并使用闪存的 Session 数据

重定向到新的 URL 的同时 传送数据给 session 是很常见的。 通常会在成功执行一个动作并传送消息给 session 之后这样做。为了方便起见,你可以创建一个 RedirectResponse 实例并在链式方法调用中将数据传送给 session :

  1. <?php
  2. Route::post('user/profile', function () {
  3. // 更新用户的个人资料...
  4. return redirect('dashboard')->with('status', 'Profile updated!');
  5. });

在用户重定向后,可以显示 session 中的传送数据。比如使用 Blade syntax

  1. @if (session('status'))
  2. <div class="alert alert-success">
  3. {{ session('status') }}
  4. </div>
  5. @endif

3. 其他响应类型

3.1 响应JSON

json 自动将 Content-Type 头信息设置为 application/json,同时使用 PHP 的 json_encode 函数将给定的数组转换为 JSON :如果直接返回数组的话,也会被包装成JSON的格式

  1. <?php
  2. # json 响应
  3. Route::get('way5', function () {
  4. return response()->json([
  5. 'name' => 'Abigail',
  6. 'state' => 'CA'
  7. ]);
  8. });

效果
image.png