響應(yīng)類擴(kuò)展了 HTTP 消息類 ,只適用于服務(wù)器返回響應(yīng)給調(diào)用它的客戶端。
響應(yīng)類被實例化并傳遞到控制器??梢酝ㄟ^ $this->response
訪問它。很多時候不需要直接使用它,因為 CodeIgniter 會為你發(fā)送標(biāo)頭和正文。 如果一切正常,頁面會成功創(chuàng)建被請求的內(nèi)容。 但是當(dāng)出現(xiàn)問題時,或者當(dāng)你需要發(fā)送指定的狀態(tài)碼,或者想要使用強(qiáng)大的 HTTP 緩存,可以立即使用它。
當(dāng)需要直接設(shè)置腳本的輸出內(nèi)容時,不要依賴CodeIgniter來自動獲取它,應(yīng)該手動調(diào)用 setBody
方法。通常用于設(shè)置響應(yīng)的狀態(tài)碼。
$this->response->setStatusCode(404)
->setBody($body);
響應(yīng)中的原因短語 (‘OK’, ‘Created’, ‘Moved Permenantly’) 將被自動添加,但也可以通過為 setStatusCode()
方法設(shè)置第二個參數(shù)來添加自定義的原因。
$this->response->setStatusCode(404, 'Nope. Not here.');
通常,你需要為響應(yīng)設(shè)置 HTTP 頭。響應(yīng)類通過 setHeader()
方法簡化了這個操作。
setHeader()
方法的第一個參數(shù)是 HTTP 頭的名稱,第二個參數(shù)是值,它可以是字符串或值的數(shù)組,當(dāng)發(fā)送到客戶端時將被正確組合。
使用這些函數(shù)而不是使用PHP原生函數(shù),可以確保不會過早發(fā)送 HTTP 頭導(dǎo)致錯誤,并使測試成為可能。
$response->setHeader('Location', 'http://example.com')
->setHeader('WWW-Authenticate', 'Negotiate');
如果 HTTP 頭已經(jīng)存在并且可以有多個值,可以使用 appendHeader()
prependHeader()
方法分別將值添加到值列表的結(jié)尾或開頭。
第一個參數(shù)是 HTTP 頭的名稱,第二個參數(shù)是添加到結(jié)尾或開頭的值。
$response->setHeader('Cache-Control', 'no-cache')
->appendHeader('Cache-Control', 'must-revalidate');
HTTP 頭可以用 removeHeader()
方法移除,此方法只接受 HTTP 頭的名稱作為唯一參數(shù)。并且不區(qū)分大小寫。
$response->removeHeader('Location');
響應(yīng)類提供了一個簡單地將文件發(fā)送給客戶端的方法,提示瀏覽器下載文件。會設(shè)置適當(dāng)?shù)臉?biāo)題來實現(xiàn)。
第一個參數(shù)是 下載文件的名稱,第二個參數(shù)是文件內(nèi)容。
如果將第二個參數(shù)設(shè)為 NULL, 并且 $filename
是一個已存在的,可讀的文件路徑,那么將會使用這個路徑下的內(nèi)容作為文件內(nèi)容。
如果將第三個參數(shù)設(shè)置為布爾值 TRUE,那么實際的文件的 MIME 類型(基于文件擴(kuò)展名)將被發(fā)送,這樣當(dāng)瀏覽器擁有該類型的處理程序 - 可以使用到它。
示例:
$data = 'Here is some text!';
$name = 'mytext.txt';
$response->download($name, $data);
如果要從服務(wù)器下載現(xiàn)有的文件,你需要這樣做:
// photo.jpg 的內(nèi)容將被自動讀取
$response->download('/path/to/photo.jpg', NULL);
內(nèi)置的 HTTP 規(guī)范是幫助客戶端(通常是web瀏覽器)緩存結(jié)果的工具。
正確使用它,可以為應(yīng)用程序帶來巨大的性能提升,因為它會告訴客戶端不需要聯(lián)系服務(wù)器,因為沒有任何改變。你不會比這更快。
這些都通過 Cache-Control
和 Etag
頭來處理。本指南并不適合完整介紹緩存的功能,但你可以在 Google Developers 和 Mobify Blog 中了解更多。
默認(rèn)情況下,所有通過 CodeIgniter 發(fā)送的響應(yīng)都是關(guān)閉了 HTTP 緩存的。 但在實際應(yīng)用中,情況千變?nèi)f化,無法簡單的設(shè)置一個合適的默認(rèn)值,除非關(guān)閉它, 不過,可以通過 setCache()
方法設(shè)置你需要的緩存的值。這非常簡單
$options = [
'max-age' => 300,
's-maxage' => 900,
'etag' => 'abcde',
];
$this->response->setCache($options);
$options
是一個簡單的鍵值對數(shù)組,它們被分配給 Cache-Control
頭。你也可以根據(jù)具體情況自由設(shè)定所有選項。
雖然大多數(shù)選項都應(yīng)用于 Cache-Control
頭,但它會智能地處理 etag
和 last-modified
選項到適當(dāng)?shù)念^。
對XSS攻擊的最佳保護(hù)方式之一是在站點上實施內(nèi)容安全策略。
這迫使你將從你網(wǎng)站的 HTML 中載入的每一個內(nèi)容來源列入白名單中,包括圖片,樣式表,JavaScript文件等。瀏覽器將拒絕白名單外的的內(nèi)容。這個白名單在響應(yīng)的 Content-Security-Policy
標(biāo)頭中創(chuàng)建,并且有多種配置方式。
這聽起來很復(fù)雜,在某些網(wǎng)站上肯定會有挑戰(zhàn)性。對于很多簡單的網(wǎng)站,所有的內(nèi)容由相同的域名(http://example.com)提供,整合起來非常簡單。
由于這是一個復(fù)雜的主題,本用戶指南將不會覆蓋所有細(xì)節(jié)。有關(guān)更多信息,你應(yīng)該訪問以下網(wǎng)站:
默認(rèn)情況下,CSP策略是禁用的。想要在應(yīng)用程序中啟用CSP,修改 application/Config/App.php 中的 CSPEnabled
的值
public $CSPEnabled = true;
當(dāng)開啟后,響應(yīng)對象將包含一個 CodeIgniter\HTTP\ContentSecurityPolicy
的實例。
在 application/Config/ContentSecurityPolicy.php 中設(shè)置的值應(yīng)用于這個實例,如果在運(yùn)行時沒有修改,那么將會發(fā)送正確的格式化后的標(biāo)題,并且完成所有操作。
如果你的應(yīng)用需要在運(yùn)行時進(jìn)行更改,則可以訪問 $response->CSP
實例。該類擁有很多方法,可以很清晰地映射到你需要設(shè)置的 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);
可以設(shè)置一個網(wǎng)站不保護(hù)自己的頁面上的內(nèi)聯(lián)腳本和樣式,因為這可能是用戶生成的內(nèi)容的結(jié)果。 為了防止這種情況,CSP 允許你再 <style> 和 <script> 標(biāo)記中指定一個隨機(jī)數(shù),并將這些值添加到響應(yīng)頭中。 這樣處理很痛苦,但是卻是最安全的。 為了簡單起見,你可以在代碼中包含 {csp-style-nonce} 或 {csp-script-nonce} 占位符,程序?qū)詣訛槟闾幚?/p>
// Original
<script {csp-script-nonce}>
console.log("Script won't run as it doesn't contain a nonce attribute");
</script>
// Becomes
<script nonce="Eskdikejidojdk978Ad8jf">
console.log("Script won't run as it doesn't contain a nonce attribute");
</script>
// OR
<style {csp-style-nonce}>
. . .
</style>
注解
除了這里列出的方法,響應(yīng)類還繼承了 消息類 的方法。
父類提供的可用的方法:
CodeIgniter\HTTP\Message::body()
CodeIgniter\HTTP\Message::setBody()
CodeIgniter\HTTP\Message::populateHeaders()
CodeIgniter\HTTP\Message::headers()
CodeIgniter\HTTP\Message::header()
CodeIgniter\HTTP\Message::headerLine()
CodeIgniter\HTTP\Message::setHeader()
CodeIgniter\HTTP\Message::removeHeader()
CodeIgniter\HTTP\Message::appendHeader()
CodeIgniter\HTTP\Message::protocolVersion()
CodeIgniter\HTTP\Message::setProtocolVersion()
CodeIgniter\HTTP\Message::negotiateMedia()
CodeIgniter\HTTP\Message::negotiateCharset()
CodeIgniter\HTTP\Message::negotiateEncoding()
CodeIgniter\HTTP\Message::negotiateLanguage()
CodeIgniter\HTTP\Message::negotiateLanguage()
CodeIgniter\HTTP\Response
statusCode
()
返回: | 此次響應(yīng)的 HTTP 狀態(tài)碼 |
---|---|
返回類型: | int |
返回此響應(yīng)的當(dāng)前狀態(tài)碼,如果沒有設(shè)置狀態(tài)碼,則會拋出 BadMethodCallException 異常。:
echo $response->statusCode();
setStatusCode
($code[, $reason=''])
參數(shù): | $code (int) – HTTP 狀態(tài)碼 |
---|---|
$reason (string) – 一個可選的原因短語 | |
返回: | 當(dāng)前的響應(yīng)實例 |
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置此次響應(yīng)的 HTTP 狀態(tài)碼
$response->setStatusCode(404);
原因短語將會根據(jù)協(xié)議規(guī)定自動的生成。如果你需要為自定義狀態(tài)碼設(shè)置自己的愿意短語,你可以將原因短語作為第二個參數(shù)傳遞
$response->setStatusCode(230, "Tardis initiated");
reason
()
返回: | 當(dāng)前的原因短語。 |
---|---|
返回類型: | string |
返回此響應(yīng)的當(dāng)前狀態(tài)碼。如果沒有設(shè)置狀態(tài),將返回一個空字符串
echo $response->reason();
setDate
($date)
參數(shù): | $date (DateTime) – 一個設(shè)置了此響應(yīng)的時間的 DateTime 實例。 |
---|---|
返回: | 當(dāng)前的響應(yīng)類實例 |
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置響應(yīng)的時間。 $date
參數(shù)必須是一個 DateTime
實例
$date = DateTime::createFromFormat('j-M-Y', '15-Feb-2016');
$response->setDate($date);
setContentType
($mime[, $charset='UTF-8'])
參數(shù): | $mime (string) – 響應(yīng)的內(nèi)容類型 |
---|---|
$charset (string) – 此響應(yīng)使用的字符集。 | |
返回: | 當(dāng)前的響應(yīng)類實例 |
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置此響應(yīng)的內(nèi)容類型
$response->setContentType('text/plain');
$response->setContentType('text/html');
$response->setContentType('application/json');
默認(rèn)情況下,該方法將字符集設(shè)置為 UTF-8
。如果你需要修改,可以將字符集作為第二個參數(shù)傳遞
$response->setContentType('text/plain', 'x-pig-latin');
noCache
()
返回: | 當(dāng)前的響應(yīng)類實例 |
---|---|
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置 Cache-Control
標(biāo)頭來關(guān)閉所有的 HTTP 緩存。這是所有響應(yīng)消息的默認(rèn)設(shè)置
$response->noCache();
// Sets the following header:
Cache-Control: no-store, max-age=0, no-cache
setCache
($options)
參數(shù): | $options (array) – 一組緩存設(shè)置的鍵值 |
---|---|
返回: | 當(dāng)前的響應(yīng)類實例 |
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置 Cache-Control
標(biāo)頭,包括 ETags
和 Last-Modified
。 典型的鍵有:
當(dāng)設(shè)置了 last-modified 選項時,它的值可以是一個 date 字符串,或一個 DateTime 對象。
setLastModified
($date)
參數(shù): | $date (string/DateTime) – 設(shè)置 Last-Modified 的時間 |
---|---|
返回: | 當(dāng)前的響應(yīng)類實例 |
返回類型: | CodeIgniter\HTTP\Response |
設(shè)置 Last-Modified
頭。 $date
可以是一個字符串或一個 DateTime
實例
$response->setLastModified(date('D, d M Y H:i:s'));
$response->setLastModified(DateTime::createFromFormat('u', $time));
send
()
返回: | 當(dāng)前的響應(yīng)類實例 |
---|---|
返回類型: | CodeIgniter\HTTP\Response |
通知響應(yīng)類發(fā)送內(nèi)容給客戶端。這將首先發(fā)送 HTTP 頭,然后是響應(yīng)的主體內(nèi)容。對于主應(yīng)用程序的響應(yīng),你不需要調(diào)用它,因為它由 CodeIgniter 自動處理。
setCookie
($name = ''[, $value = ''[, $expire = ''[, $domain = ''[, $path = '/'[, $prefix = ''[, $secure = FALSE[, $httponly = FALSE]]]]]]])
參數(shù): | $name (mixed) – Cookie 名稱或參數(shù)數(shù)組 |
---|---|
$value (string) – Cookie 值 | |
$expire (int) – Cookie 過期時間,單位:秒 | |
$domain (string) – Cookie 作用域 | |
$path (string) – Cookie 可用的路徑 | |
$prefix (string) – Cookie 前綴 | |
$secure (bool) – 是否只通過 HTTPS 傳輸 Cookie | |
$httponly (bool) – 是否只允許 HTTP 請求讀取cookie,JavaScript不可以讀取 | |
返回類型: | void |
設(shè)置一個包含你指定的值的 Cookie 。有兩種將信息傳遞給該方法的方式:數(shù)組和獨立參數(shù):
數(shù)組方式
使用此方法,將關(guān)聯(lián)數(shù)組傳遞給第一個參數(shù)
$cookie = array(
'name' => 'The Cookie Name',
'value' => 'The Value',
'expire' => '86500',
'domain' => '.some-domain.com',
'path' => '/',
'prefix' => 'myprefix_',
'secure' => TRUE
);
$response->setCookie($cookie);
注意事項
只需要名稱和值。要刪除 Cookie ,將其設(shè)置為過期即可。
過期時間使用 秒數(shù) , 將從當(dāng)前時間開始計算。
不要設(shè)置為一個具體的時間,而只是從 now 開始的你希望 Cookie 有效的秒數(shù)。
如果過期時間設(shè)置為零,Cookie 將只在瀏覽器打開時有效,瀏覽器關(guān)閉時則被清除。
對于整站的 Cookie , 無論你的網(wǎng)站是被如何請求的,請將你的網(wǎng)址添加到到 domain 中并且以 . 開始,例如: .your-domain.com
通常不需要該路徑,因為默認(rèn)已經(jīng)設(shè)置了根目錄。
僅當(dāng)你需要避免與服務(wù)器的其他相同命名的 Cookie 沖突時,才需要前綴。
僅當(dāng)你想要加密 Cookie 時才需要設(shè)置 secure 項為 TRUE。
獨立參數(shù)
如果你愿意,也可以使用單個參數(shù)傳遞數(shù)據(jù)來設(shè)置 Cookie。
$response->setCookie($name, $value, $expire, $domain, $path, $prefix, $secure);
更多建議: