CodeIgniter4 HTTP 響應(yīng)

2020-08-17 15:48 更新

響應(yīng)類擴(kuò)展了 HTTP 消息類 ,只適用于服務(wù)器返回響應(yīng)給調(diào)用它的客戶端。

使用響應(yīng)類

響應(yīng)類被實例化并傳遞到控制器??梢酝ㄟ^ $this->response 訪問它。很多時候不需要直接使用它,因為 CodeIgniter 會為你發(fā)送標(biāo)頭和正文。 如果一切正常,頁面會成功創(chuàng)建被請求的內(nèi)容。 但是當(dāng)出現(xiàn)問題時,或者當(dāng)你需要發(fā)送指定的狀態(tài)碼,或者想要使用強(qiáng)大的 HTTP 緩存,可以立即使用它。

設(shè)置輸出內(nèi)容

當(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.');

設(shè)置 HTTP 頭

通常,你需要為響應(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);

HTTP 緩存

內(nèi)置的 HTTP 規(guī)范是幫助客戶端(通常是web瀏覽器)緩存結(jié)果的工具。

正確使用它,可以為應(yīng)用程序帶來巨大的性能提升,因為它會告訴客戶端不需要聯(lián)系服務(wù)器,因為沒有任何改變。你不會比這更快。

這些都通過 Cache-ControlEtag 頭來處理。本指南并不適合完整介紹緩存的功能,但你可以在 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 頭,但它會智能地處理 etaglast-modified 選項到適當(dāng)?shù)念^。

內(nèi)容安全策略(CSP)

對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)站:

啟用CSP

默認(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ùn)行時配置

如果你的應(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);

內(nèi)聯(lián)內(nèi)容

可以設(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)頭,包括 ETagsLast-Modified 。 典型的鍵有:

  • etag
  • last-modified
  • max-age
  • s-maxage
  • private
  • public
  • must-revalidate
  • proxy-revalidate
  • no-transform

當(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);
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號