HTTP 响应¶
响应类扩展了 HTTP 消息类 ,只适用于服务器返回响应给调用它的客户端。
使用响应类¶
响应类被实例化并传递到控制器。可以通过 $this->response
访问它。很多时候不需要直接使用它,因为 CodeIgniter 会为你发送标头和正文。
如果一切正常,页面会成功创建被请求的内容。
但是当出现问题时,或者当你需要发送指定的状态码,或者想要使用强大的 HTTP 缓存,可以立即使用它。
设置输出内容¶
当需要直接设置脚本的输出内容时,不要依赖CodeIgniter来自动获取它,应该手动调用 setBody
方法。通常用于设置响应的状态码。
$this->response->setStatusCode(404)
->setBody($body);
响应中的原因短语 (‘OK’, ‘Created’, ‘Moved Permenantly’) 将被自动添加,但也可以通过为 setStatusCode()
方法设置第二个参数来添加自定义的原因。
$this->response->setStatusCode(404, 'Nope. Not here.');
设置 HTTP 头¶
通常,你需要为响应设置 HTTP 头。响应类通过 setHeader()
方法简化了这个操作。
setHeader()
方法的第一个参数是 HTTP 头的名称,第二个参数是值,它可以是字符串或值的数组,当发送到客户端时将被正确组合。
使用这些函数而不是使用PHP原生函数,可以确保不会过早发送 HTTP 头导致错误,并使测试成为可能。
$response->setHeader('Location', 'http://example.com')
->setHeader('WWW-Authenticate', 'Negotiate');
如果 HTTP 头已经存在并且可以有多个值,可以使用 appendHeader()
prependHeader()
方法分别将值添加到值列表的结尾或开头。
第一个参数是 HTTP 头的名称,第二个参数是添加到结尾或开头的值。
$response->setHeader('Cache-Control', 'no-cache')
->appendHeader('Cache-Control', 'must-revalidate');
HTTP 头可以用 removeHeader()
方法移除,此方法只接受 HTTP 头的名称作为唯一参数。并且不区分大小写。
$response->removeHeader('Location');
文件下载¶
响应类提供了一个简单地将文件发送给客户端的方法,提示浏览器下载文件。会设置适当的标题来实现。
第一个参数是 下载文件的名称,第二个参数是文件内容。
如果将第二个参数设为 NULL, 并且 $filename
是一个已存在的,可读的文件路径,那么将会使用这个路径下的内容作为文件内容。
如果将第三个参数设置为布尔值 TRUE,那么实际的文件的 MIME 类型(基于文件扩展名)将被发送,这样当浏览器拥有该类型的处理程序 - 可以使用到它。
示例:
$data = 'Here is some text!';
$name = 'mytext.txt';
$response->download($name, $data);
如果要从服务器下载现有的文件,你需要这样做:
// photo.jpg 的内容将被自动读取
$response->download('/path/to/photo.jpg', NULL);
HTTP 缓存¶
内置的 HTTP 规范是帮助客户端(通常是web浏览器)缓存结果的工具。
正确使用它,可以为应用程序带来巨大的性能提升,因为它会告诉客户端不需要联系服务器,因为没有任何改变。你不会比这更快。
这些都通过 Cache-Control
和 Etag
头来处理。本指南并不适合完整介绍缓存的功能,但你可以在 Google Developers 和 Mobify Blog 中了解更多。
默认情况下,所有通过 CodeIgniter 发送的响应都是关闭了 HTTP 缓存的。
但在实际应用中,情况千变万化,无法简单的设置一个合适的默认值,除非关闭它,
不过,可以通过 setCache()
方法设置你需要的缓存的值。这非常简单
$options = [
'max-age' => 300,
's-maxage' => 900,
'etag' => 'abcde',
];
$this->response->setCache($options);
$options
是一个简单的键值对数组,它们被分配给 Cache-Control
头。你也可以根据具体情况自由设定所有选项。
虽然大多数选项都应用于 Cache-Control
头,但它会智能地处理 etag
和 last-modified
选项到适当的头。
内容安全策略(CSP)¶
对XSS攻击的最佳保护方式之一是在站点上实施内容安全策略。
这迫使你将从你网站的 HTML 中载入的每一个内容来源列入白名单中,包括图片,样式表,JavaScript文件等。浏览器将拒绝白名单外的的内容。这个白名单在响应的 Content-Security-Policy
标头中创建,并且有多种配置方式。
这听起来很复杂,在某些网站上肯定会有挑战性。对于很多简单的网站,所有的内容由相同的域名(http://example.com)提供,整合起来非常简单。
由于这是一个复杂的主题,本用户指南将不会覆盖所有细节。有关更多信息,你应该访问以下网站:
启用CSP¶
默认情况下,CSP策略是禁用的。想要在应用程序中启用CSP,修改 application/Config/App.php 中的 CSPEnabled
的值
public $CSPEnabled = true;
当开启后,响应对象将包含一个 CodeIgniter\HTTP\ContentSecurityPolicy
的实例。
在 application/Config/ContentSecurityPolicy.php 中设置的值应用于这个实例,如果在运行时没有修改,那么将会发送正确的格式化后的标题,并且完成所有操作。
运行时配置¶
如果你的应用需要在运行时进行更改,则可以访问 $response->CSP
实例。该类拥有很多方法,可以很清晰地映射到你需要设置的 header 头
$reportOnly = true;
$response->CSP->reportOnly($reportOnly);
$response->CSP->setBaseURI('example.com', true);
$response->CSP->setDefaultSrc('cdn.example.com', $reportOnly);
$response->CSP->setReportURI('http://example.com/csp/reports');
$response->CSP->setSandbox(true, ['allow-forms', 'allow-scripts']);
$response->CSP->upgradeInsecureRequests(true);
$response->CSP->addChildSrc('https://youtube.com', $reportOnly);
$response->CSP->addConnectSrc('https://*.facebook.com', $reportOnly);
$response->CSP->addFontSrc('fonts.example.com', $reportOnly);
$response->CSP->addFormAction('self', $reportOnly);
$response->CSP->addFrameAncestor('none', $reportOnly);
$response->CSP->addImageSrc('cdn.example.com', $reportOnly);
$response->CSP->addMediaSrc('cdn.example.com', $reportOnly);
$response->CSP->addObjectSrc('cdn.example.com', $reportOnly);
$response->CSP->addPluginType('application/pdf', $reportOnly);
$response->CSP->addScriptSrc('scripts.example.com', $reportOnly);
$response->CSP->addStyleSrc('css.example.com', $reportOnly);