簡介
dart:html包為dart提供了構建瀏覽器客戶端的一些必須的元件,之前我們提到了HTML和DOM的操作,除了這些之外,我們在瀏覽器端另一個常用的操作就是使用XMLHttpRequest去做非同步HTTP資源的請求,也就是AJAX請求。
dart同樣提供了類似JS中XMLHttpRequest的封裝,其對應的類叫做HttpRequest,一起來看看在dart中怎麼使用HttpRequest吧。
傳送GET請求
雖然現代的web APP被各種框架所封裝,但是歸根結底他還是一個AJAX的富客戶端應用。我們通過各種非同步的HTTP請求向伺服器端請求資料,然後展示在頁面上。一般來說資料的互動格式是JSON,當然也可以有其他的資料互動格式。
AJAX中最常用的方式就是向伺服器端傳送get請求,對應的HttpRequest有一個getString方法:
static Future<String> getString(String url,
{bool? withCredentials, void onProgress(ProgressEvent e)?}) {
return request(url,
withCredentials: withCredentials, onProgress: onProgress)
.then((HttpRequest xhr) => xhr.responseText!);
}
注意,getString方法是一個類方法,所以直接使用HttpRequest類來呼叫:
var name = Uri.encodeQueryComponent('John');
var id = Uri.encodeQueryComponent('42');
HttpRequest.getString('users.json?name=$name&id=$id')
.then((String resp) {
// Do something with the response.
});
因為getString返回的是一個Future,所以可以直接在getString後面接then語句,來獲取返回的值。
當然,你也可以在async方法中使用await來獲取返回值。
Future<void> main() async {
String pageHtml = await HttpRequest.getString(url);
// Do something with pageHtml...
}
或者使用try catch來捕獲異常:
try {
var data = await HttpRequest.getString(jsonUri);
// Process data...
} catch (e) {
// Handle exception...
}
傳送post請求
GET是從伺服器拉取資料,相應的POST就是通用的向伺服器中提交資料的方法。在HttpRequest中,對應的方法是postFormData:
static Future<HttpRequest> postFormData(String url, Map<String, String> data,
{bool? withCredentials,
String? responseType,
Map<String, String>? requestHeaders,
void onProgress(ProgressEvent e)?}) {
var parts = [];
data.forEach((key, value) {
parts.add('${Uri.encodeQueryComponent(key)}='
'${Uri.encodeQueryComponent(value)}');
});
var formData = parts.join('&');
if (requestHeaders == null) {
requestHeaders = <String, String>{};
}
requestHeaders.putIfAbsent('Content-Type',
() => 'application/x-www-form-urlencoded; charset=UTF-8');
return request(url,
method: 'POST',
withCredentials: withCredentials,
responseType: responseType,
requestHeaders: requestHeaders,
sendData: formData,
onProgress: onProgress);
}
從方法的實現上可以看到,預設情況下使用的Content-Type: application/x-www-form-urlencoded; charset=UTF-8, 也就是說預設是以form表單提交的形式進行的。
在這種情況下,對於承載資料的data來說,會首先進行Uri.encodeQueryComponent進行編碼,然後再使用&進行連線。
下面是使用的例子:
var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
// Do something with the response.
});
注意,postFormData中返回的是一個HttpRequest,雖然它叫做Request,但是實際上可以包含response的內容。所以直接使用他獲取返回內容即可。
更加通用的操作
上面我們講解了get和form的post,從程式碼可以看到,他們底層實際上都呼叫的是request方法。request是一個更加通用的HTTP請求方法。可以支援POST
, PUT
, DELETE
等HTTP操作。下面是request的方法定義:
static Future<HttpRequest> request(String url,
{String? method,
bool? withCredentials,
String? responseType,
String? mimeType,
Map<String, String>? requestHeaders,
sendData,
void onProgress(ProgressEvent e)?})
其中sendData可以是[ByteBuffer],[Blob], [Document], [String], 或者 [FormData] 等格式。
responseType表示的是HttpRequest.responseType,是返回物件的格式,預設情況下是String,也可以是'arraybuffer', 'blob', 'document', 'json', 或者 'text'。
下面是一個是直接使用request的例子:
var myForm = querySelector('form#myForm');
var data = new FormData(myForm);
HttpRequest.request('/submit', method: 'POST', sendData: data)
.then((HttpRequest resp) {
// Do something with the response.
});
總結
使用HttpRequest可以直接模擬瀏覽器中的Ajax操作,非常方便。
本文已收錄於 http://www.flydean.com/21-dart-http/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!