處理 HTTP 請求?

為了充分地使用 CodeIgniter,你需要對 HTTP 請求和響應(yīng)的工作方式有基本的了解。因為在開發(fā)Web應(yīng)用時需要處理 HTTP 請求,所以對于所有想要成功的開發(fā)者來說, 理解 HTTP 背后的概念是 必須 的。

本章的第一部分會給出一些關(guān)于 HTTP 的概述,接著我們會討論怎樣用 CodeIgniter 來處理 HTTP 請求與響應(yīng)。

什么是 HTTP ??

HTTP 是兩臺計算機相互通信的一種基于文本的協(xié)議。當(dāng)瀏覽器請求頁面時,它會詢問服務(wù)器是否可以獲取該頁面。然后, 服務(wù)器準(zhǔn)備頁面并將響應(yīng)發(fā)送回發(fā)送請求的瀏覽器。就是這樣簡單,也可以說復(fù)雜些,但基本就是這樣。

HTTP 是用于描述該交換約定的術(shù)語。它代表超文本傳輸協(xié)議(Hypertext Transfer Protocol)。開發(fā) web 應(yīng)用程序時, 你的目標(biāo)只是了解瀏覽器的要求,并能夠做出適當(dāng)?shù)捻憫?yīng)。

HTTP 請求?

當(dāng)客戶端(瀏覽器,手機軟件等)嘗試發(fā)送 HTTP 請求時,客戶端會向服務(wù)器發(fā)出一條文本消息然后等待響應(yīng)。

這條文本消息會像這樣:

GET / HTTP/1.1
Host codeigniter.com
Accept: text/html
User-Agent: Chrome/46.0.2490.80

這條消息包含了所有服務(wù)器可能需要的信息。比如它請求的 method(GET,POST,DELETE 等)、它所支持的 HTTP 版本。

該請求還包括許多可選的請求頭字段,這些頭字段可以包含各種信息,例如客戶端希望內(nèi)容顯示為哪種語言, 客戶端接受的格式類型等等。 Wikipedia 上有一篇文章,列出了 所有的請求頭字段 (譯者注:國內(nèi)用戶如果無法訪問的話, 可以查看 在MDN上的頁面 )。

HTTP 響應(yīng)?

服務(wù)器收到請求后,你的 web 應(yīng)用程序會處理這條信息然后輸出一些響應(yīng)結(jié)果。服務(wù)器會將你的響應(yīng)結(jié)果打包為對 客戶端的的你的響應(yīng)結(jié)果打包為對客戶端的響應(yīng)的一部分。服務(wù)器對客戶端的響應(yīng)消息看起來會像這樣:

HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Thu, 05 Nov 2015 05:33:22 GMT
Content-Type: text/html; charset=UTF-8

<html>
        . . .
</html>

響應(yīng)消息告訴客戶端服務(wù)器正在使用的 HTTP 版本規(guī)范,以及響應(yīng)狀態(tài)碼(200)。狀態(tài)碼是標(biāo)準(zhǔn)化的對客戶端具有非常特定 含義的代碼。它可以告訴客戶端響應(yīng)成功(200),或者找不到頁面(404)等等。 在 IANA 可以找到 完整的響應(yīng)狀態(tài)碼列表 。

對 HTTP 請求和響應(yīng)的處理?

雖然 PHP 提供了與 HTTP 請求和響應(yīng)進行交互的原生方式,但 CodeIgniter 像大多數(shù)框架一樣,將它們抽象化,讓你擁有一個 一致、簡單的接口。IncomingRequest 類 類是 HTTP 請求的面向?qū)ο蟮谋硎拘问健?它提供你所需要的一切:

use CodeIgniter\HTTP\IncomingRequest;

$request = service('request');

// 請求的 uri(如 /about )
$request->uri->getPath();

// 檢索 $_GET 與 $_POST 變量
$request->getGet('foo');
$request->getPost('foo');

// 從 $_REQUEST 檢索,其中應(yīng)同時包含 $_GET 和 $_POST 內(nèi)容
$request->getVar('foo');

// 從 AJAX 調(diào)用中檢索 JSON
$request->getJSON();

// 檢索 server 變量
$request->getServer('Host');

// 檢索 HTTP 請求頭,使用不區(qū)分大小寫的名稱
$request->getHeader('host');
$request->getHeader('Content-Type');

$request->getMethod();  // GET, POST, PUT 等等

request 類會在后臺為你做很多工作,你無需擔(dān)心。 isAJAX()isSecure() 函數(shù)會自動檢查幾種不同的 method 來 最后確定正確的答案。

注解

isAJAX() 函數(shù)依賴于 X-Requested-With 頭部,這個頭部在一些情況下,不會在 XHR 請求中通過 JavaScript 默認(rèn)發(fā)送。想要了解如何避免這個問題,請參考 AJAX Requests 章節(jié)

CodeIgniter 還提供了 Response 類 ,它是 HTTP 響應(yīng)的面向?qū)ο笫奖硎尽?它為你提供一種簡單而強大的方法來構(gòu)造對客戶的響應(yīng):

use CodeIgniter\HTTP\Response;

$response = service('response');

$response->setStatusCode(Response::HTTP_OK);
$response->setBody($output);
$response->setHeader('Content-type', 'text/html');
$response->noCache();

// 把響應(yīng)結(jié)果發(fā)給瀏覽器
$response->send();

另外, Response 類 還允許你處理 HTTP 緩存層以獲得最佳性能。