响应
当应用完成处理一个请求后, 会生成一个response响应对象并发送给终端用户 响应对象包含的信息有HTTP状态码,HTTP头和主体内容等, 网页应用开发的最终目的本质上就是根据不同的请求构建这些响应对象。
状态码
构建响应时,最先应做的是标识请求是否成功处理的状态,可通过设置 yii\web\Response::statusCode 属性,该属性使用一个有效的 HTTP 状态码。
yii\web\Response::statusCode 状态码默认为200, 如果需要指定请求失败,可抛出对应的HTTP异常
throw new \yii\web\NotFoundHttpException;
创建一个yii\web\HttpException异常, 带上状态码抛出,如下:
throw new \yii\web\HttpException(402);
响应主体
响应是html
大多数情况下是通过 操作 方法的返回值隐式地设置
public function actionIndex()
{
return $this->render('index');
}
响应是json
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->data = ['message' => 'hello world'];
浏览器跳转
public function actionOld()
{
return $this->redirect('http://example.com/new', 301);
}
也可以可直接调用yii\web\Response::redirect() 再调用 yii\web\Response::send() 方法来确保没有其他内容追加到响应中。
\Yii::$app->response->redirect('http://example.com/new', 301)->send();
如果当前请求为AJAX 请求, 发送一个 Location
头不会自动使浏览器跳转,为解决这个问题, yii\web\Response::redirect() 方法设置一个值为要跳转的URL的X-Redirect
头, 在客户端可编写JavaScript 代码读取该头部值然后让浏览器跳转对应的URL。
信息:Yii 配备了一个
yii.js
JavaScript 文件提供常用JavaScript功能, 包括基于X-Redirect
头的浏览器跳转, 因此,如果你使用该JavaScript 文件(通过yii\web\YiiAsset 资源包注册), 就不需要编写AJAX跳转的代码。
发送文件
public function actionDownload()
{
return \Yii::$app->response->sendFile('path/to/file.txt');
}
如果不是在操作方法中调用文件发送方法,在后面还应调用 yii\web\Response::send() 没有其他内容追加到响应中。
\Yii::$app->response->sendFile('path/to/file.txt')->send();
发送响应
在yii\web\Response::send() 方法调用前响应中的内容不会发送给用户, 该方法默认在yii\base\Application::run() 结尾自动调用,尽管如此,可以明确调用该方法强制立即发送响应。
yii\web\Response::send() 方法使用以下步骤来发送响应:
- 触发 yii\web\Response::EVENT_BEFORE_SEND 事件.
- 调用 yii\web\Response::prepare() 来格式化 response data 为 response content.
- 触发 yii\web\Response::EVENT_AFTER_PREPARE 事件.
- 调用 yii\web\Response::sendHeaders() 来发送注册的HTTP头
- 调用 yii\web\Response::sendContent() 来发送响应主体内容
- 触发 yii\web\Response::EVENT_AFTER_SEND 事件.
一旦yii\web\Response::send() 方法被执行后,其他地方调用该方法会被忽略, 这意味着一旦响应发出后,就不能再追加其他内容。
如你所见yii\web\Response::send() 触发了几个实用的事件, 通过响应这些事件可调整或包装响应。