上篇文章中,我們完成了第一個dart服務(wù)器,輸出了Hello World!今天,我們來學(xué)習(xí)處理請求,獲取請求方法,獲取請求參數(shù),獲取請求頭,那開始學(xué)習(xí)吧!
1. 處理請求
在上一節(jié)中,我們對所有請求都回復(fù)它一個Hello World!這個信息,我們現(xiàn)在改變一下,添加一個方法,傳入request,把Hello World!這一條注釋掉
//....
//監(jiān)聽請求
await for(HttpRequest request in requestServer){
//監(jiān)聽到請求后response回復(fù)它一個Hello World!然后關(guān)閉這個請求
// request.response..write('Hello World!')
// ..close();
handleMessage(request);
}
}
void handleMessage(HttpRequest request){
//在這個方法里面處理請求
}
一般情況下,我們是不知道別人要對我們服務(wù)器做什么的,如果服務(wù)器出現(xiàn)異常而崩潰掉,就會影響其它用戶的訪問,所以,我們需要try..catch里面處理請求,以防止客戶端惡意請求
//....
void handleMessage(HttpRequest request){
try{
//在這里處理請求
}catch(e){
print('出現(xiàn)了一個異常,異常為:$e');
}
print('請求被處理了');
}
2. 請求方法
request這個對象里面,有一個method變量,這個變量就是請求的方法了,我們是可以通過request.method獲取,請求方法有下面幾種!
| 請求類型 | 含義 |
|---|---|
| request.method=='GET' | 當(dāng)前為GET請求(一般為訪問資源) |
| request.method=='POST' | 當(dāng)前為POST請求 (一般為提交數(shù)據(jù)) |
| request.method=='PUT' | 當(dāng)前為PUT請求(一般為特定位置上傳資源) |
| request.method=='DELETE' | 當(dāng)前為DELETE請求(一般為刪除資源) |
| request.method=='TRACE' | 當(dāng)前為TRACE請求(一般用于測試或診斷) |
| request.method=='CONNECT' | 當(dāng)前為CONNECT請求 (一般為代理服務(wù)) |
| request.method=='HEAD' | 當(dāng)前為HEAD請求 (一般獲取響應(yīng)消息頭) |
| request.method=='OPTIONS' | 當(dāng)前為OPTIONS請求 (一般獲取服務(wù)器支持的請求方法) |
好了,我們知道了可以使用request.method來獲取請求方法,那么對于一般服務(wù)器來說,只用到GET或者POST,所以,我們對不是GET或者POST的請求回應(yīng)不支持該請求
void handleMessage(HttpRequest request){
try{
if(request.method=='GET'){
//獲取到GET請求
handleGET(request);
}else if(request.method=='POST'){
//獲取到POST請求
handlePOST(request);
}else{
//其它的請求方法暫時不支持,回復(fù)它一個狀態(tài)
request.response..statusCode=HttpStatus.methodNotAllowed
..write('對不起,不支持${request.method}方法的請求!')
..close();
}
}catch(e){
print('出現(xiàn)了一個異常,異常為:$e');
}
print('請求被處理了');
}
void handleGET(HttpRequest request){
//處理GET請求
}
void handlePOST(HttpRequest request){
//處理POST請求
}
上面我們看到了一個新的東西,就是request.response..statusCode ,這個變量呢,是對客戶端返回一個狀態(tài)碼,我們熟悉的狀態(tài)碼有200(ok),404(鏈接不存在)等等,下面,我們學(xué)習(xí)一下dart內(nèi)置的狀態(tài)碼有哪些(有同學(xué)可能會疑問,為什么使用“ .. ”而不是使用“ . ”呢,這個就是dart的一個語法,通過" .. " 我們可以不斷的調(diào)用第一次“ .. ”的那個對象的方法,簡直愛死這個操作有沒有,有點語法糖的味道)
3. 狀態(tài)碼
HttpStatus這個類是一個抽象類,里面定義的一連串的狀態(tài)碼
abstract class HttpStatus {
//繼續(xù)
static const int continue_ = 100;
//交換協(xié)議
static const int switchingProtocols = 101;
//可以
static const int ok = 200;
//已創(chuàng)建
static const int created = 201;
//認(rèn)可的
static const int accepted = 202;
//非授權(quán)信息
static const int nonAuthoritativeInformation = 203;
//沒有內(nèi)容
static const int noContent = 204;
//重置內(nèi)容
static const int resetContent = 205;
//部分內(nèi)容
static const int partialContent = 206;
//多項選擇
static const int multipleChoices = 300;
//永久遷移
static const int movedPermanently = 301;
//已發(fā)現(xiàn)
static const int found = 302;
//臨時遷移
static const int movedTemporarily = 302; // Common alias for found.
//查看其它
static const int seeOther = 303;
//未修改的
static const int notModified = 304;
//使用代理
static const int useProxy = 305;
//暫時重定向
static const int temporaryRedirect = 307;
//請求失敗
static const int badRequest = 400;
//沒有授權(quán)
static const int unauthorized = 401;
//要求付款
static const int paymentRequired = 402;
//被禁止
static const int forbidden = 403;
//未找到
static const int notFound = 404;
//請求方法不允許
static const int methodNotAllowed = 405;
//不接受
static const int notAcceptable = 406;
//需要代理身份認(rèn)證
static const int proxyAuthenticationRequired = 407;
//請求超時
static const int requestTimeout = 408;
//沖突
static const int conflict = 409;
//過去了
static const int gone = 410;
//長度要求
static const int lengthRequired = 411;
//先決條件失敗
static const int preconditionFailed = 412;
//請求實體過大
static const int requestEntityTooLarge = 413;
//請求地址過長
static const int requestUriTooLong = 414;
//非支持的媒體類型
static const int unsupportedMediaType = 415;
//請求范圍不可滿足
static const int requestedRangeNotSatisfiable = 416;
//期望失敗
static const int expectationFailed = 417;
//升級要求
static const int upgradeRequired = 426;
//內(nèi)部服務(wù)器錯誤
static const int internalServerError = 500;
//未實現(xiàn)
static const int notImplemented = 501;
//網(wǎng)關(guān)壞了
static const int badGateway = 502;
//服務(wù)不可用
static const int serviceUnavailable = 503;
//網(wǎng)關(guān)超時
static const int gatewayTimeout = 504;
//http版本不支持
static const int httpVersionNotSupported = 505;
// 連接超時
static const int networkConnectTimeoutError = 599;
}
4.獲取請求的參數(shù)
當(dāng)接收到請求時,客戶端傳遞一個參數(shù)給我,我們應(yīng)該怎樣去獲取呢?
這里我們需要用到 request.uri 這個變量,這個變量主要包含了請求的資源,例如:主機(jī),地址,端口,查詢字符串等等,那么現(xiàn)在,我們定義一個變量為id,當(dāng)接收到這個id時,返回一個字符串為'當(dāng)前查詢的id為:$id'
void handleGET(HttpRequest request){
//獲取一個參數(shù)
var id=request.uri.queryParameters['id'];//查詢id的值
request.response
..statusCode=HttpStatus.ok//回復(fù)它一個ok狀態(tài),說明我收到請求啦
..write('當(dāng)前查詢的id為$id')//顯示到瀏覽器的內(nèi)容
..close();//我已經(jīng)回復(fù)你了,所以關(guān)閉這個請求
}
好了,我們按照之前的方法,啟動服務(wù)器吧!然后到瀏覽器輸入 http://localhost:8080?id=123
(這里因為是GET請求,所以,可以直接在鏈接上面?zhèn)魅氩樵儏?shù),一般以 鏈接?key=value 的形式傳入,key 對應(yīng)為 id ,value對應(yīng)為id的值,我們有不同的參數(shù),就以 鏈接?key1=value1&key2=value2 這種形式傳入)

可以看到,我們很成功的獲取到id的值。
5.請求頭
獲取請求頭,我們也是很容易就可以獲取到的,可以通過
request.headers獲取到
request.headers.forEach((key,values){
print('key:$key');
for(String value in values){
print('value:$value');
}
});
上面代碼,可以打印出客戶端請求的詳細(xì)請求頭

今天我們學(xué)習(xí)了如何處理請求,獲取請求方法,獲取請求參數(shù),獲取請求頭,好了,明天見!
如果想繼續(xù)學(xué)習(xí)DartVM服務(wù)器開發(fā),請關(guān)注我,學(xué)習(xí)更多騷操作!