×
贴子
课程
动态
签到
更新
直播间
系统
碎片
订阅
话题
文档
序言
发布说明
升级指南
贡献指南
开始使用
安装
配置
目录结构
Homestead
Valet
部署
核心架构
请求生命周期
服务容器
服务提供者
Facades
Contracts
基础功能
路由
中间件
CSRF 保护
控制器
请求
响应
视图
URL
表单验证
Session
错误处理
日志
前端开发
Blade 模板
本地化
前端指南
编辑资源 Mix
安全相关
用户认证
用户授权
Email 授权
加密解密
哈希
重置密码
深层发掘
Artisan 命令行
广播系统
缓存系统
集合
事件系统
文件存储
辅助函数
邮件发送
消息通知
扩展包开发
队列
任务调度
数据库
入门
查询构造器
分页
数据库迁移
数据填充
Redis
Eloquent ORM
入门
模型关联
Eloquent 集合
修改器
API 资源
序列化
测试相关
入门指南
HTTP测试
控制台测试
浏览器测试(Laravel Dusk)
数据库测试
测试模拟器
官方扩展包
Cashier
Envoy 部署工具
Horizon
Scout
Laravel 社会化登录
基础功能
Laravel 5.7 中文文档
/
响应
# 响应 ## 创建响应 ### 字符串 & 数组 所有路由和控制器都应返回响应以发送回用户的浏览器。Laravel提供了几种不同的方式来返回响应。最基本的响应是从路由或控制器返回一个字符串。框架会自动将字符串转换为完整的HTTP响应: ```php Route::get('/', function () { return 'Hello World'; }); ``` 除了从路由和控制器返回字符串之外,您还可以返回数组。该框架将自动将数组转换为JSON响应: ```php Route::get('/', function () { return [1, 2, 3]; }); ``` > 您是否知道您还可以从您的路由或控制器返回[Eloquent系列](https://laravel.com/docs/5.7/eloquent-collections)?它们将自动转换为JSON。试一试! ### 响应对象 通常,您不只是从路由操作返回简单的字符串或数组。相反,您将返回完整的`Illuminate\Http\Response`实例或[视图](https://laravel.com/docs/5.7/views)。 返回完整`Response`实例允许您自定义响应的HTTP状态代码和响应头信息。`Response`实例继承`Symfony\Component\HttpFoundation\Response`类,它提供了多种用于构建HTTP应答的方法:` ```php Route::get('home', function () { return response('Hello World', 200) ->header('Content-Type', 'text/plain'); }); ``` ### 为响应增加头信息 请记住,大多数响应方法都是可链式调用的,使得创建响应实例的过程更具可读性。例如,您可以使用该`header`方法向响应添加一系列标头,然后再将其发送回用户: ```php return response($content) ->header('Content-Type', $type) ->header('X-Header-One', 'Header Value') ->header('X-Header-Two', 'Header Value'); ``` 或者,您可以使用该`withHeaders`方法指定要添加到响应的头信息数组: ```php return response($content) ->withHeaders([ 'Content-Type' => $type, 'X-Header-One' => 'Header Value', 'X-Header-Two' => 'Header Value', ]); ``` ### 将Cookie附加到响应中 `cookie`响应实例上的方法允许您轻松地将cookie附加到响应。例如,您可以使用该`cookie`方法生成cookie并将其轻松地附加到响应实例,如下所示: ```php return response($content) ->header('Content-Type', $type) ->cookie('name', 'value', $minutes); ``` 该`cookie`方法还接受一些较少使用的参数。通常,这些参数与PHP的 [setcookie](https://secure.php.net/manual/en/function.setcookie.php)方法的参数具有相同的目的和意义: ```php ->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly) ``` 或者,您可以使用`Cookie`Facade“队列”,cookie以附加到应用程序的传出响应。`queue`方法接受`Cookie`创建`Cookie`实例所需的实例或参数。这些cookie将在发送到浏览器之前附加到传出响应中: ```php Cookie::queue(Cookie::make('name', 'value', $minutes)); Cookie::queue('name', 'value', $minutes); ``` ### Cookie和加密 默认情况下,Laravel生成的所有cookie都经过加密和签名,以便客户端无法修改或读取它们。如果要对应用程序生成的cookie子集禁用加密,可以使用`App\Http\Middleware\EncryptCookies`中间件的`$except`属性,该属性位于`app/Http/Middleware`目录中: ```php /** * The names of the cookies that should not be encrypted. * * @var array */ protected $except = [ 'cookie_name', ]; ``` ## 重定向 重定向响应是`Illuminate\Http\RedirectResponse`类的实例,并包含将用户重定向到另一个URL所需的正确头信息。有几种方法可以生成`RedirectResponse`实例。最简单的方法是使用全局辅助函数 `redirect`: ```php Route::get('dashboard', function () { return redirect('home/dashboard'); }); ``` 有时您可能希望将用户重定向到之前的位置,例如提交的表单无效时。您可以使用全局`back`帮助程序功能执行此操作。由于此功能使用[会话](https://laravel.com/docs/5.7/session),因此请确保调用该`back`功能的路由正在使用`web`中间件组或已应用所有`Session`中间件: ```php Route::post('user/profile', function () { // Validate the request... return back()->withInput(); }); ``` ### 重定向到命名路由 当您不带参数调用辅助函数 `redirect` 时,会返回一个`Illuminate\Routing\Redirector`实例,允许您调用`Redirector`实例上的任何方法。例如,要生成`RedirectResponse`到命名路由,您可以使用`route`方法: ```php return redirect()->route('login'); ``` 如果您的路由有参数,您可以将它们作为方法的第二个参数传递`route`: ```php // For a route with the following URI: profile/{id} return redirect()->route('profile', ['id' => 1]); ``` #### 通过Eloquent模型填充参数 如果要重定向到具有从Eloquent模型填充“ID”参数的路由,则可以传递模型本身。ID将自动提取: ```php // For a route with the following URI: profile/{id} return redirect()->route('profile', [$user]); ``` 如果要自定义路径参数中的值,则应覆盖`getRouteKey`Eloquent模型上的方法: ```php /** * Get the value of the model's route key. * * @return mixed */ public function getRouteKey() { return $this->slug; } ``` ### 重定向到控制器操作 您还可以生成重定向到[控制器操作](https://laravel.com/docs/5.7/controllers)。为此,请将控制器和操作名称传递给`action`方法。请记住,您不需要为控制器指定完整的命名空间,因为Laravel的 `RouteServiceProvider`将自动设置基本控制器命名空间: ```php return redirect()->action('HomeController@index'); ``` 如果您的控制器路由需要参数,您可以将它们作为方法的第二个参数传递给`action`方法: ```php return redirect()->action( 'UserController@profile', ['id' => 1] ); ``` ### 重定向到外部域 有时您可能需要重定向到应用程序之外的域名。您可以通过调用`away`方法来执行此操作,它会创建一个 `RedirectResponse`无需任何其他URL编码,验证或认证: ```php return redirect()->away('https://www.google.com'); ``` ### 重定向并使用闪存的 Session 数据 重定向到新URL并将[数据闪存到Session](https://laravel.com/docs/5.7/session#flash-data)通常是同时完成的。通常,在将成功消息闪存到会话后成功执行操作后,即可完成此操作。为方便起见,您可以创建一个`RedirectResponse`实例使用简单、快捷的链式操作给 session 闪存数据 ```php Route::post('user/profile', function () { // Update the user's profile... return redirect('dashboard')->with('status', 'Profile updated!'); }); ``` 重定向用户后,你可以从 [session](https://laravel-china.org/docs/laravel/5.7/session) 中读取闪存的信息。例如,使用[Blade语法](https://laravel.com/docs/5.7/blade): ```php @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif ``` ## 其他响应类型 使用辅助函数 `response` 可以用来生成其他类型的响应实例。在`response`不带参数的情况下调用帮助程序时,将返回`Illuminate\Contracts\Routing\ResponseFactory`[契约](https://laravel.com/docs/5.7/contracts)的实现。该契约提供了几种有用的方法来生成响应。 ### 视图响应 如果您需要控制响应的状态和标题,但还需要返回[视图](https://laravel.com/docs/5.7/views)作为响应的内容,则应使用以下`view`方法: ```php return response() ->view('hello', $data, 200) ->header('Content-Type', $type); ``` 当然,如果您不需要传递自定义HTTP状态代码或自定义头信息,则应该使用全局辅助函数 `view`。 ### JSON相应 `json` 方法会自动把 `Content-Type` 响应头信息设置为 `application/json`,并使用 PHP函数 `json_encode` 将给定的数组转换为 JSON: ```php return response()->json([ 'name' => 'Abigail', 'state' => 'CA' ]); ``` 如果您想创建JSONP响应,可以将该`json`方法与该`withCallback`方法结合使用: ```php return response() ->json(['name' => 'Abigail', 'state' => 'CA']) ->withCallback($request->input('callback')); ``` ### 文件下载 `download`方法可用于生成强制用户的浏览器在给定路径下载文件的响应。该`download`方法接受文件名作为方法的第二个参数,这将确定下载文件的用户看到的文件名。最后,您可以将HTTP响应头数组作为方法的第三个参数传递: ```php return response()->download($pathToFile); return response()->download($pathToFile, $name, $headers); return response()->download($pathToFile)->deleteFileAfterSend(); ``` > 管理文件下载的Symfony HttpFoundation要求下载的文件名必须是 ASCII 编码的。 ### 流媒体下载 有时您可能希望将给定操作的字符串响应转换为可下载的响应,而不必将操作的内容写入磁盘。您可以在此方案中使用使用`streamDownload`方法。此方法接受回调,文件名和可选的标题数组作为其参数: ```php return response()->streamDownload(function () { echo GitHub::api('repo') ->contents() ->readme('laravel', 'laravel')['contents']; }, 'laravel-readme.md'); ``` ### 文件响应 `file`方法可用于直接在用户的浏览器中显示文件,例如图像或PDF,而不是启动下载。此方法接受文件的路径作为其第一个参数,并头信息数组作为其第二个参数: ```php return response()->file($pathToFile); return response()->file($pathToFile, $headers); ``` ## 响应宏 如果要定义可在各种路径和控制器中重复使用的自定义响应,可以在 `Response` Facade 上使用 `macro` 方法。例如,从[服务提供器](https://laravel.com/docs/5.7/providers) 的 `boot`方法这样写: ```php <?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`函数接受一个名称作为其第一个参数,并接受一个闭包作为其第二个参数。从`ResponseFactory`实现或辅助函数 `response` 调用时,其闭包将会被执行 : ```php return response()->caps('foo'); ```