mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 05:48:11 +08:00
@ -1,13 +1,13 @@
|
|||||||
响应
|
响应
|
||||||
=========
|
=========
|
||||||
|
|
||||||
当一个应用在处理完一个[请求](runtime-requests.md)后, 这个应用会生成一个[[yii\web\Response|response]]响应对象并把这个响应对象发送给终端用户
|
当一个应用在处理完一个[请求](runtime-requests.md)后, 这个应用会生成一个 [[yii\web\Response|response]] 响应对象并把这个响应对象发送给终端用户
|
||||||
这个响应对象包含的信息有HTTP状态码,HTTP头和主体内容等,
|
这个响应对象包含的信息有HTTP状态码,HTTP头和主体内容等,
|
||||||
从本质上说,网页应用开发最终的目标就是根据不同的请求去构建这些响应对象。
|
从本质上说,网页应用开发最终的目标就是根据不同的请求去构建这些响应对象。
|
||||||
|
|
||||||
在大多数实际应用情况下,你应该主要地去处理`response`这个 [应用组件](structure-application-components.md),
|
在大多数实际应用情况下,你应该主要地去处理 `response` 这个 [应用组件](structure-application-components.md),
|
||||||
在默认情况下,它是一个继承自[[yii\web\Response]]的实例
|
在默认情况下,它是一个继承自 [[yii\web\Response]] 的实例
|
||||||
然而,Yii也允许你创建自己的响应对象并发送给终端用户,这方面在后续会阐述。
|
然而,Yii 也允许你创建自己的响应对象并发送给终端用户,这方面在后续会阐述。
|
||||||
|
|
||||||
在本节,我们将会讲述如何组装和构建响应并把它发送给终端用户。
|
在本节,我们将会讲述如何组装和构建响应并把它发送给终端用户。
|
||||||
|
|
||||||
@ -24,8 +24,8 @@ Yii::$app->response->statusCode = 200;
|
|||||||
```
|
```
|
||||||
|
|
||||||
尽管如此,大多数情况下不需要明确设置状态码,
|
尽管如此,大多数情况下不需要明确设置状态码,
|
||||||
因为 [[yii\web\Response::statusCode]] 状态码默认为200,
|
因为 [[yii\web\Response::statusCode]] 状态码默认为 200,
|
||||||
如果需要指定请求失败,可抛出对应的HTTP异常,如下所示:
|
如果需要指定请求失败,可抛出对应的 HTTP 异常,如下所示:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
throw new \yii\web\NotFoundHttpException;
|
throw new \yii\web\NotFoundHttpException;
|
||||||
@ -47,7 +47,7 @@ throw new \yii\web\NotFoundHttpException;
|
|||||||
* [[yii\web\UnauthorizedHttpException]]:状态码 401。
|
* [[yii\web\UnauthorizedHttpException]]:状态码 401。
|
||||||
* [[yii\web\UnsupportedMediaTypeHttpException]]:状态码 415。
|
* [[yii\web\UnsupportedMediaTypeHttpException]]:状态码 415。
|
||||||
|
|
||||||
如果想抛出的异常不在如上列表中,可创建一个[[yii\web\HttpException]]异常,
|
如果想抛出的异常不在如上列表中,可创建一个 [[yii\web\HttpException]] 异常,
|
||||||
带上状态码抛出,如下:
|
带上状态码抛出,如下:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -57,7 +57,7 @@ throw new \yii\web\HttpException(402);
|
|||||||
|
|
||||||
## HTTP 头部 <span id="http-headers"></span>
|
## HTTP 头部 <span id="http-headers"></span>
|
||||||
|
|
||||||
可在 `response` 组件中操控[[yii\web\Response::headers|header collection]]来发送HTTP头部信息,
|
可在 `response` 组件中操控 [[yii\web\Response::headers|header collection]] 来发送 HTTP 头部信息,
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -81,7 +81,7 @@ $values = $headers->remove('Pragma');
|
|||||||
|
|
||||||
大多是响应应有一个主体存放你想要显示给终端用户的内容。
|
大多是响应应有一个主体存放你想要显示给终端用户的内容。
|
||||||
|
|
||||||
如果已有格式化好的主体字符串,可赋值到响应的[[yii\web\Response::content]]属性,
|
如果已有格式化好的主体字符串,可赋值到响应的 [[yii\web\Response::content]] 属性,
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -99,7 +99,7 @@ $response->data = ['message' => 'hello world'];
|
|||||||
```
|
```
|
||||||
|
|
||||||
Yii支持以下可直接使用的格式,每个实现了[[yii\web\ResponseFormatterInterface|formatter]] 类,
|
Yii支持以下可直接使用的格式,每个实现了[[yii\web\ResponseFormatterInterface|formatter]] 类,
|
||||||
可自定义这些格式器或通过配置[[yii\web\Response::formatters]] 属性来增加格式器。
|
可自定义这些格式器或通过配置 [[yii\web\Response::formatters]] 属性来增加格式器。
|
||||||
|
|
||||||
* [[yii\web\Response::FORMAT_HTML|HTML]]: 通过 [[yii\web\HtmlResponseFormatter]] 来实现.
|
* [[yii\web\Response::FORMAT_HTML|HTML]]: 通过 [[yii\web\HtmlResponseFormatter]] 来实现.
|
||||||
* [[yii\web\Response::FORMAT_XML|XML]]: 通过 [[yii\web\XmlResponseFormatter]]来实现.
|
* [[yii\web\Response::FORMAT_XML|XML]]: 通过 [[yii\web\XmlResponseFormatter]]来实现.
|
||||||
@ -107,7 +107,7 @@ Yii支持以下可直接使用的格式,每个实现了[[yii\web\ResponseForma
|
|||||||
* [[yii\web\Response::FORMAT_JSONP|JSONP]]: 通过 [[yii\web\JsonResponseFormatter]]来实现.
|
* [[yii\web\Response::FORMAT_JSONP|JSONP]]: 通过 [[yii\web\JsonResponseFormatter]]来实现.
|
||||||
* [[yii\web\Response::FORMAT_RAW|RAW]]: use this format if you want to send the response directly without applying any formatting.
|
* [[yii\web\Response::FORMAT_RAW|RAW]]: use this format if you want to send the response directly without applying any formatting.
|
||||||
|
|
||||||
上述响应主体可明确地被设置,但是在大多数情况下是通过 [操作](structure-controllers.md)
|
上述响应主体可明确地被设置,但是在大多数情况下是通过[操作](structure-controllers.md)
|
||||||
方法的返回值隐式地设置,常用场景如下所示:
|
方法的返回值隐式地设置,常用场景如下所示:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
@ -120,7 +120,7 @@ public function actionIndex()
|
|||||||
上述的 `index` 操作返回 `index` 视图渲染结果,
|
上述的 `index` 操作返回 `index` 视图渲染结果,
|
||||||
返回值会被 `response` 组件格式化后发送给终端用户。
|
返回值会被 `response` 组件格式化后发送给终端用户。
|
||||||
|
|
||||||
因为响应格式默认为[[yii\web\Response::FORMAT_HTML|HTML]], 只需要在操作方法中返回一个字符串,
|
因为响应格式默认为 [[yii\web\Response::FORMAT_HTML|HTML]],只需要在操作方法中返回一个字符串,
|
||||||
如果想使用其他响应格式,应在返回数据前先设置格式,
|
如果想使用其他响应格式,应在返回数据前先设置格式,
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
@ -159,12 +159,12 @@ public function actionInfo()
|
|||||||
|
|
||||||
## 浏览器跳转 <span id="browser-redirection"></span>
|
## 浏览器跳转 <span id="browser-redirection"></span>
|
||||||
|
|
||||||
浏览器跳转依赖于发送一个`Location` HTTP 头,因为该功能通常被使用,
|
浏览器跳转依赖于发送一个 `Location` HTTP 头,因为该功能通常被使用,
|
||||||
Yii提供对它提供了特别的支持。
|
Yii提供对它提供了特别的支持。
|
||||||
|
|
||||||
可调用[[yii\web\Response::redirect()]] 方法将用户浏览器跳转到一个URL地址,该方法设置合适的
|
可调用[[yii\web\Response::redirect()]] 方法将用户浏览器跳转到一个 URL 地址,该方法设置合适的
|
||||||
带指定URL的 `Location` 头并返回它自己为响应对象,在操作的方法中,
|
带指定 URL 的 `Location` 头并返回它自己为响应对象,在操作的方法中,
|
||||||
可调用缩写版[[yii\web\Controller::redirect()]],例如:
|
可调用缩写版 [[yii\web\Controller::redirect()]],例如:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
public function actionOld()
|
public function actionOld()
|
||||||
@ -173,7 +173,7 @@ public function actionOld()
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
在如上代码中,操作的方法返回`redirect()` 方法的结果,如前所述,
|
在如上代码中,操作的方法返回 `redirect()` 方法的结果,如前所述,
|
||||||
操作的方法返回的响应对象会被当总响应发送给终端用户。
|
操作的方法返回的响应对象会被当总响应发送给终端用户。
|
||||||
|
|
||||||
除了动作方法外,可直接调用[[yii\web\Response::redirect()]] 再调用
|
除了动作方法外,可直接调用[[yii\web\Response::redirect()]] 再调用
|
||||||
@ -183,29 +183,29 @@ public function actionOld()
|
|||||||
\Yii::$app->response->redirect('http://example.com/new', 301)->send();
|
\Yii::$app->response->redirect('http://example.com/new', 301)->send();
|
||||||
```
|
```
|
||||||
|
|
||||||
> Info: [[yii\web\Response::redirect()]] 方法默认会设置响应状态码为302,该状态码会告诉浏览器请求的资源
|
> Info: [[yii\web\Response::redirect()]] 方法默认会设置响应状态码为 302,该状态码会告诉浏览器请求的资源
|
||||||
*临时* 放在另一个URI地址上,可传递一个301状态码告知浏览器请求
|
*临时* 放在另一个 URI 地址上,可传递一个 301 状态码告知浏览器请求
|
||||||
的资源已经 *永久* 重定向到新的URId地址。
|
的资源已经 *永久* 重定向到新的 URId 地址。
|
||||||
|
|
||||||
如果当前请求为AJAX 请求,
|
如果当前请求为 AJAX 请求,
|
||||||
发送一个 `Location` 头不会自动使浏览器跳转,为解决这个问题,
|
发送一个 `Location` 头不会自动使浏览器跳转,为解决这个问题,
|
||||||
[[yii\web\Response::redirect()]] 方法设置一个值为要跳转的URL的`X-Redirect` 头,
|
[[yii\web\Response::redirect()]] 方法设置一个值为要跳转的URL的 `X-Redirect` 头,
|
||||||
在客户端可编写JavaScript
|
在客户端可编写 JavaScript
|
||||||
代码读取该头部值然后让浏览器跳转对应的URL。
|
代码读取该头部值然后让浏览器跳转对应的 URL。
|
||||||
|
|
||||||
> Info: Yii 配备了一个`yii.js` JavaScript 文件提供常用JavaScript功能,
|
> Info: Yii 配备了一个 `yii.js` JavaScript 文件提供常用 JavaScript 功能,
|
||||||
包括基于`X-Redirect`头的浏览器跳转,
|
包括基于 `X-Redirect` 头的浏览器跳转,
|
||||||
因此,如果你使用该JavaScript 文件(通过[[yii\web\YiiAsset]] 资源包注册),
|
因此,如果你使用该 JavaScript 文件(通过 [[yii\web\YiiAsset]] 资源包注册),
|
||||||
就不需要编写AJAX跳转的代码。
|
就不需要编写 AJAX 跳转的代码。
|
||||||
|
|
||||||
## 发送文件 <span id="sending-files"></span>
|
## 发送文件 <span id="sending-files"></span>
|
||||||
|
|
||||||
和浏览器跳转类似,文件发送是另一个依赖指定HTTP头的功能,
|
和浏览器跳转类似,文件发送是另一个依赖指定 HTTP 头的功能,
|
||||||
Yii提供方法集合来支持各种文件发送需求,它们对HTTP头都有内置的支持。
|
Yii 提供方法集合来支持各种文件发送需求,它们对 HTTP 头都有内置的支持。
|
||||||
|
|
||||||
- [[yii\web\Response::sendFile()]]: 发送一个已存在的文件到客户端
|
- [[yii\web\Response::sendFile()]]:发送一个已存在的文件到客户端
|
||||||
- [[yii\web\Response::sendContentAsFile()]]: 发送一个文本字符串作为文件到客户端
|
- [[yii\web\Response::sendContentAsFile()]]:发送一个文本字符串作为文件到客户端
|
||||||
- [[yii\web\Response::sendStreamAsFile()]]: 发送一个已存在的文件流作为文件到客户端
|
- [[yii\web\Response::sendStreamAsFile()]]:发送一个已存在的文件流作为文件到客户端
|
||||||
|
|
||||||
这些方法都将响应对象作为返回值,如果要发送的文件非常大,应考虑使用
|
这些方法都将响应对象作为返回值,如果要发送的文件非常大,应考虑使用
|
||||||
[[yii\web\Response::sendStreamAsFile()]] 因为它更节约内存,
|
[[yii\web\Response::sendStreamAsFile()]] 因为它更节约内存,
|
||||||
@ -225,11 +225,11 @@ public function actionDownload()
|
|||||||
\Yii::$app->response->sendFile('path/to/file.txt')->send();
|
\Yii::$app->response->sendFile('path/to/file.txt')->send();
|
||||||
```
|
```
|
||||||
|
|
||||||
一些浏览器提供特殊的名为*X-Sendfile*的文件发送功能,
|
一些浏览器提供特殊的名为 *X-Sendfile* 的文件发送功能,
|
||||||
原理为将请求跳转到服务器上的文件,
|
原理为将请求跳转到服务器上的文件,
|
||||||
Web应用可在服务器发送文件前结束,为使用该功能,
|
Web 应用可在服务器发送文件前结束,为使用该功能,
|
||||||
可调用[[yii\web\Response::xSendFile()]],
|
可调用 [[yii\web\Response::xSendFile()]],
|
||||||
如下简要列出一些常用Web服务器如何启用`X-Sendfile` 功能:
|
如下简要列出一些常用 Web 服务器如何启用 `X-Sendfile` 功能:
|
||||||
|
|
||||||
- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile)
|
- Apache: [X-Sendfile](http://tn123.org/mod_xsendfile)
|
||||||
- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file)
|
- Lighttpd v1.4: [X-LIGHTTPD-send-file](http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file)
|
||||||
@ -241,22 +241,22 @@ Web应用可在服务器发送文件前结束,为使用该功能,
|
|||||||
## 发送响应 <span id="sending-response"></span>
|
## 发送响应 <span id="sending-response"></span>
|
||||||
|
|
||||||
在[[yii\web\Response::send()]] 方法调用前响应中的内容不会发送给用户,
|
在[[yii\web\Response::send()]] 方法调用前响应中的内容不会发送给用户,
|
||||||
该方法默认在[[yii\base\Application::run()]]
|
该方法默认在 [[yii\base\Application::run()]]
|
||||||
结尾自动调用,尽管如此,可以明确调用该方法强制立即发送响应。
|
结尾自动调用,尽管如此,可以明确调用该方法强制立即发送响应。
|
||||||
|
|
||||||
[[yii\web\Response::send()]] 方法使用以下步骤来发送响应:
|
[[yii\web\Response::send()]] 方法使用以下步骤来发送响应:
|
||||||
|
|
||||||
1. 触发 [[yii\web\Response::EVENT_BEFORE_SEND]] 事件.
|
1. 触发 [[yii\web\Response::EVENT_BEFORE_SEND]] 事件。
|
||||||
2. 调用 [[yii\web\Response::prepare()]] 来格式化 [[yii\web\Response::data|response data]] 为
|
2. 调用 [[yii\web\Response::prepare()]] 来格式化 [[yii\web\Response::data|response data]] 为
|
||||||
[[yii\web\Response::content|response content]].
|
[[yii\web\Response::content|response content]]。
|
||||||
3. 触发 [[yii\web\Response::EVENT_AFTER_PREPARE]] 事件.
|
3. 触发 [[yii\web\Response::EVENT_AFTER_PREPARE]] 事件。
|
||||||
4. 调用 [[yii\web\Response::sendHeaders()]] 来发送注册的HTTP头
|
4. 调用 [[yii\web\Response::sendHeaders()]] 来发送注册的HTTP头
|
||||||
5. 调用 [[yii\web\Response::sendContent()]] 来发送响应主体内容
|
5. 调用 [[yii\web\Response::sendContent()]] 来发送响应主体内容
|
||||||
6. 触发 [[yii\web\Response::EVENT_AFTER_SEND]] 事件.
|
6. 触发 [[yii\web\Response::EVENT_AFTER_SEND]] 事件。
|
||||||
|
|
||||||
一旦[[yii\web\Response::send()]] 方法被执行后,其他地方调用该方法会被忽略,
|
一旦 [[yii\web\Response::send()]] 方法被执行后,其他地方调用该方法会被忽略,
|
||||||
这意味着一旦响应发出后,就不能再追加其他内容。
|
这意味着一旦响应发出后,就不能再追加其他内容。
|
||||||
|
|
||||||
如你所见[[yii\web\Response::send()]] 触发了几个实用的事件,
|
如你所见 [[yii\web\Response::send()]] 触发了几个实用的事件,
|
||||||
通过响应这些事件可调整或包装响应。
|
通过响应这些事件可调整或包装响应。
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user