public function actionInfo() { return \Yii::createObject([ 'class' => 'yii\web\Response', 'format' => \yii\web\Response::FORMAT_JSON, 'data' => [ 'message' => 'hello world', 'code' => 100, ], ]); }
注意: 如果创建你自己的响应对象,将不能在应用配置中设置 response 组件,尽管如此, 可使用 依赖注入 应用通用配置到你新的响应对象。
4.浏览器跳转
浏览器跳转依赖于发送一个Location HTTP 头,因为该功能通常被使用,Yii提供对它提供了特别的支持。
可调用yii\web\Response::redirect() 方法将用户浏览器跳转到一个URL地址,该方法设置合适的 带指定URL的 Location 头并返回它自己为响应对象,在操作的方法中,可调用缩写版yii\web\Controller::redirect(),例如:
public function actionOld() { return $this->redirect('http://example.com/new', 301); }
在如上代码中,操作的方法返回redirect() 方法的结果,如前所述,操作的方法返回的响应对象会被当总响应发送给终端用户。
除了操作方法外,可直接调用yii\web\Response::redirect() 再调用 yii\web\Response::send() 方法来确保没有其他内容追加到响应中。
\Yii::$app->response->redirect('http://example.com/new', 301)->send();
补充: yii\web\Response::redirect() 方法默认会设置响应状态码为302,该状态码会告诉浏览器请求的资源 临时 放在另一个URI地址上,可传递一个301状态码告知浏览器请求的资源已经 永久 重定向到新的URId地址。
如果当前请求为AJAX 请求,发送一个 Location 头不会自动使浏览器跳转,为解决这个问题, yii\web\Response::redirect() 方法设置一个值为要跳转的URL的X-Redirect 头, 在客户端可编写JavaScript 代码读取该头部值然后让浏览器跳转对应的URL。
补充: Yii 配备了一个yii.js JavaScript 文件提供常用JavaScript功能,包括基于X-Redirect头的浏览器跳转, 因此,如果你使用该JavaScript 文件(通过yii\web\YiiAsset 资源包注册),就不需要编写AJAX跳转的代码。
5.发送文件
和浏览器跳转类似,文件发送是另一个依赖指定HTTP头的功能,Yii提供方法集合来支持各种文件发送需求,它们对HTTP头都有内置的支持。
yii\web\Response::sendFile(): 发送一个已存在的文件到客户端
yii\web\Response::sendContentAsFile(): 发送一个文本字符串作为文件到客户端
yii\web\Response::sendStreamAsFile(): 发送一个已存在的文件流作为文件到客户端
这些方法都将响应对象作为返回值,如果要发送的文件非常大,应考虑使用 yii\web\Response::sendStreamAsFile() 因为它更节约内存,以下示例显示在控制器操作中如何发送文件:
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();
一些浏览器提供特殊的名为X-Sendfile的文件发送功能,原理为将请求跳转到服务器上的文件, Web应用可在服务器发送文件前结束,为使用该功能,可调用yii\web\Response::xSendFile(), 如下简要列出一些常用Web服务器如何启用X-Sendfile 功能:
Apache: X-Sendfile Lighttpd v1.4: X-LIGHTTPD-send-file Lighttpd v1.5: X-Sendfile Nginx: X-Accel-Redirect Cherokee: X-Sendfile and X-Accel-Redirect
6.发送响应
在yii\web\Response::send() 方法调用前响应中的内容不会发送给用户,该方法默认在yii\base\Application::run() 结尾自动调用,尽管如此,可以明确调用该方法强制立即发送响应。
yii\web\Response::send() 方法使用以下步骤来发送响应:
触发 yii\web\Response::EVENT_BEFORE_SEND 事件.
调用 yii\web\Response::prepare() 来格式化 yii\web\Response::data 为 yii\web\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() 触发了几个实用的事件,通过响应这些事件可调整或包装响应。
您可能感兴趣的文章: