Cookieを適切に処理しながら(たとえば、サーバーから送信されたCookieを保存し、後続の要求を行うときにそれらのCookieを送信する)、リモートサーバーにhttpリクエストを送信したいと思います。すべてのCookieを保存しておくと便利です
私が使用しているhttpリクエスト
static Future<Map> postData(Map data) async {
http.Response res = await http.post(url, body: data); // post api call
Map data = JSON.decode(res.body);
return data;
}
次に、セッションCookieを取得し、後続のリクエストでそれを返す方法の例を示します。複数のCookieを返すように簡単に調整できます。 Session
クラスを作成し、GET
sとPOST
sをすべてルーティングします。
class Session {
Map<String, String> headers = {};
Future<Map> get(String url) async {
http.Response response = await http.get(url, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
Future<Map> post(String url, dynamic data) async {
http.Response response = await http.post(url, body: data, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
void updateCookie(http.Response response) {
String rawCookie = response.headers['set-cookie'];
if (rawCookie != null) {
int index = rawCookie.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie : rawCookie.substring(0, index);
}
}
}
Cookie対応のHTTPリクエストを支援するために、 requests という小さなフラッターライブラリを公開しました。
dependencies:
requests: ^1.0.0
使用法:
import 'package:requests/requests.Dart';
// ...
// this will persist cookies
await Requests.post("https://example.com/api/v1/login", body: {"username":"...", "password":"..."} );
// this will re-use the persisted cookies
dynamic data = await Requests.get("https://example.com/api/v1/stuff", json: true);
Richard Heapのソリューションを改善して、複数の「セットCookie」と複数のCookieを処理できるようにしました。
私の場合、サーバーは複数の「Set-cookies」を返します。 httpパッケージは、すべてのset-cookiesヘッダーを1つのヘッダーに連結し、コンマ( '、')で区切ります。
class NetworkService {
final JsonDecoder _decoder = new JsonDecoder();
final JsonEncoder _encoder = new JsonEncoder();
Map<String, String> headers = {"content-type": "text/json"};
Map<String, String> cookies = {};
void _updateCookie(http.Response response) {
String allSetCookie = response.headers['set-cookie'];
if (allSetCookie != null) {
var setCookies = allSetCookie.split(',');
for (var setCookie in setCookies) {
var cookies = setCookie.split(';');
for (var cookie in cookies) {
_setCookie(cookie);
}
}
headers['cookie'] = _generateCookieHeader();
}
}
void _setCookie(String rawCookie) {
if (rawCookie.length > 0) {
var keyValue = rawCookie.split('=');
if (keyValue.length == 2) {
var key = keyValue[0].trim();
var value = keyValue[1];
// ignore keys that aren't cookies
if (key == 'path' || key == 'expires')
return;
this.cookies[key] = value;
}
}
}
String _generateCookieHeader() {
String cookie = "";
for (var key in cookies.keys) {
if (cookie.length > 0)
cookie += ";";
cookie += key + "=" + cookies[key];
}
return cookie;
}
Future<dynamic> get(String url) {
return http.get(url, headers: headers).then((http.Response response) {
final String res = response.body;
final int statusCode = response.statusCode;
_updateCookie(response);
if (statusCode < 200 || statusCode > 400 || json == null) {
throw new Exception("Error while fetching data");
}
return _decoder.convert(res);
});
}
Future<dynamic> post(String url, {body, encoding}) {
return http
.post(url, body: _encoder.convert(body), headers: headers, encoding: encoding)
.then((http.Response response) {
final String res = response.body;
final int statusCode = response.statusCode;
_updateCookie(response);
if (statusCode < 200 || statusCode > 400 || json == null) {
throw new Exception("Error while fetching data");
}
return _decoder.convert(res);
});
}
}