Laravel 文档阅读: HTTP 响应
创建响应
字符串 & 数组
用户的每个请求无一例外得都要给予一个响应。Laravel 提供了几种不同的响应方式。最简单的响应是从路由或控制器中返回一个字符串。Laravel 会将这个字符串自动转换为完整的 HTTP 响应。
Route::get('/', function () {
return 'Hello World';
});
除了返回字符串,还可以返回一个数组。Laravel 会将这个数组自动转换为 JSON 响应。
Route::get('/', function () {
return [1, 2, 3];
});
小提示:从路由或控制器中返回的 Eloquent 集合也会被自动转换为 JSON 响应哦~
响应对象
我们一般不会只返回一个字符串或者数组。相反,我们经常返回完整的 Illuminate\Http\Response
实例或者视图。
返回一个 Response
实例的话,允许我们自定义 HTTP 响应码和标头。Response
实例继承了 Symfony\Component\HttpFoundation\Response
类,提供了大量构建 HTTP 响应的方法:
Route::get('home', function () {
return response('hello world', 200)
->header('Content-Type', 'text/plain');
});
为响应附加标头
记住,Response
实例的大多数方法都是可以链式调用的。例如,你可以连续使用几次 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',
]);
为响应附加 Cookie
使用 cookie
方法为响应附加 Cookie,向下面这样:
return response($content)
->header('Content-Type', $type)
->cookie('name', 'value', $minutes);
cookie
方法还接收一些参数,不过不常用。如果要使用,只要记住,cookie
方法的签名和原生 PHP 方法 setcookie
是一样的:
->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
Cookie & 加密
默认,Laravel 生成的所有 Cookie 都会经过加密和签名处理,不能被客户端修改和读取。如果需要列出一个「白名单」,不用对名单里的 Cookie 加密的话,就要用到 App\Http\Middleware\EncryptCookies
中间件的 $except
属性,位于 app/Http/Middleware
目录下:
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
'cookie_name',
];
重定向
重定向响应是 Illuminate\Http\RedirectResponse
实例,并且包含重定向所需的正确标头信息。有几种生成 RedirectResponse
实例的方式。最简单的是使用全局 redirect
辅助函数:
Route::get('dashboard', function () {
return redirect('home/dashboard');
});
有时需要重定向到之前地址,比如当提交表单无效时。这时可以使用 back
辅助函数。因为这个函数使用了 Session,所以要保证调用 call
函数的路由使用了 web
中间件组或者是应用了所有的 Session 相关中间件:
Route::post('user/profile', function () {
// Validate the request...
return back()->withInput();
});
重定向到命名路由
直接调用 redirect()
方法会返回一个 Illuminate\Routing\Redirector
实例,你就可以使用这个实例上的方法了。例如,你可以使用 route
方法产生一个到命名路由的 RedirectResponse
实例:
return redirect()->route('login');
如果路由包含参数,给 route
方法传递第二个参数指定:
// For a route with the following URI: profile/{id}
return redirect()->route('profile', ['id' => 1]);
使用 Eloquent Model 填充路由参数
如果你重定向的那个路由包含一个叫 id
的路由参数,那么可以向 route
方法直接传递 Eloquent Model 实例。ID 值会被自动解析:
// For a route with the following URI: profile/{id}
return redirect()->route('profile', [$user]);
如果路由参数使用的不是 id
,而是其他字段名(比如 email
),那这个时候就需要在 Eloquent Model 设置 getRouteKey
方法了,告诉 Laravel 从 Eloquent Model 中解析 email
这个字段值给路由参数:
/**
* Get the value of the model's route key.
*
* @return mixed
*/
public function getRouteKey()
{
return $this->email;
}
重定向到控制器 Action
给 action
方法传递控制器和 action 名就可以重定向到某个控制器 action。记住,你无需指定包含完整命名空间的控制器类名,只需指定 App\Http\Controllers
后面那部分的内容,这是在 Laravel 的 RouteServiceProvider
中设定的:
return redirect()->action('HomeController@index');
如果路由包含参数,给 action
方法传递第二个参数指定:
return redirect()->route(
'UserController@profile', ['id' => 1]
);
重定向时携带 Session 闪存数据
重定向到一个新 URL,并且闪存数据到 Session 经常同时进行。比如,我们在成功操作某一个动作后,返回一条提示操作成功的消息。为了方便,你可以在 RedirectResponse
实例上直接使用 with
方法将消息闪存到 Session 中,一行代码搞定!
Route::post('user/profile', function () {
// Update the user's profile...
return redirect('dashboard')->with('status', 'Profile updated!');
});
重定向后,就可以从 Session 中获得闪存消息了。下面以 Blade 模板文件为例,展示消息内容:
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
其他响应类型
response
辅助函数可以产生其他类型的响应实例。当以无参的形式调用 response
函数的时候,也就是 response()
——它会返回一个实现了 Illuminate\Contracts\Routing\ResponseFactory
契约的实例。在这个契约里提供了一些有用的产生响应的方法。
视图响应
如果需要指定响应的状态码、标头,而且还要返回一个视图,可以使用 view
方法:
return response()
->view('hello', $data, 200)
->header('Content-Type', $type);
当然,如果不用自定义响应状态码或者标头,直接返回视图,那么用全局 view
辅助函数完全 OK。
JSON 响应
json
方法会自动设置 Content-Type
标头为 application/json
,并且使用 PHP json_encode
函数将数组转换为 JSON 数据:
return response()->json([
'name' => 'Abigail',
'state' => 'CA'
]);
如果需要创建一个 JSONP 响应,可以让 json
方法结合 withCallback
方法使用:
return response()
->json(['name' => 'Abigail', 'state' => 'CA'])
->withCallback($request->input('callback'));
文件下载
download
方法强制浏览器下载指定路径下的文件。该方法接收第二个参数作为文件名(最终用户看到的文件名)。最后,你可以传递第三个包含标头信息的数组参数:
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
return response()->download($pathToFile)->deleteFileAfterSend(true);
注意!管理文件下载的 Symfony HttpFoundation 需要下载的文件具有 ASCII 文件名。
文件响应
file
方法用来强制显示文件,比如图片和 PDF 文件(而不是下载)。该方法的第一个参数是文件路径,第二个参数是包含标头信息的数组:
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
响应宏
可以使用 Response
门面的 macro
方法,自定义可以在各种路由和控制器中重复使用的响应,这就是「响应宏」。例如,在服务提供者的 boot
方法里设置咱们的响应宏:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
class ResponseMacroServiceProvider extends ServiceProvider
{
/**
* Register the application's response macros.
*
* @return void
*/
public function boot()
{
Response::macro('caps', function ($value) {
return Response::make(strtoupper($value));
});
}
}
macro
函数的第一个参数是宏的名字,第二个参数是闭包。宏的闭包会在调用 response
辅助函数时候被执行,或者是从 ResponseFactory
的实现调用宏的时候被执行。
return response()->caps('foo');
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: