Je voudrais faire une demande http à un serveur distant tout en gérant correctement les cookies (par exemple, stocker des cookies envoyés par le serveur et envoyer ces cookies lorsque je fais des demandes ultérieures). Ce serait bien de conserver tous les cookies
pour la demande http que j'utilise
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;
}
Voici un exemple de la façon de récupérer un cookie de session et de le renvoyer lors des requêtes suivantes. Vous pouvez facilement l'adapter pour renvoyer plusieurs cookies. Créez une classe Session
et acheminez tous vos GET
s et POST
s à travers elle.
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);
}
}
}
J'ai publié une petite bibliothèque de flutter appelée requêtes pour aider avec les requêtes http compatibles avec les cookies.
dependencies:
requests: ^1.0.0
Usage:
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);
J'ai amélioré la solution de Richard Heap pour pouvoir traiter plusieurs "Set-cookies" et plusieurs cookies.
Dans mon cas, le serveur renvoie plusieurs "Set-cookies". Le package http concatène tous les en-têtes set-cookies dans un en-tête et le sépare par une virgule (',').
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);
});
}
}