Laravel 文档阅读: HTTP 响应

翻译、衍生自:https://learnku.com/docs/laravel/5.5/responses

创建响应

字符串 & 数组

用户的每个请求无一例外得都要给予一个响应。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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!