尝试使用 HttpClient:
Future<HttpClientResponse> httpRequest(String url, Map headers, Map body, {bool isQuery = false}) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
headers.forEach((key, value) {
request.headers.set(key,value);
});
if(isQuery) {
request.headers.set('content-type', 'application/query+json');
request.headers.set('x-ms-documentdb-isquery', 'True');
}
if(body != null) {
request.add(utf8.encode(json.encode(body)));
}
HttpClientResponse response = await request.close();
httpClient.close();
return response;
}
请注意,您需要将标题设置为 1 到 1。
一个只做 SELECT 查询的便捷函数:
Future<HttpClientResponse> doSELECTQuery(String userAgent, List<String> requiredColHeaders, String azTblName,
{Map<String,String> mapWHERE, String pKey, String pKey_Filter, Map<String, String> moreHeaders, String alternateCollectionUrl = null}) async {
String _collectionUrl;
String _host;
Uri uri = Uri.tryParse(alternateCollectionUrl);
if(uri != null) {
_host = uri.host;
}
_collectionUrl = alternateCollectionUrl;
} else {
_collectionUrl = this.collectionUrl;
_host = this.host;
}
String collectionPath = Uri.parse(_collectionUrl).path.substring(1); // remove leading "/"
Map<String, String> headers = {
"authorization": generateAuthToken(
"POST", "docs", collectionPath, HttpDate.format(DateTime.now()),
masterKey, "master"),
"x-ms-version": "2018-12-31",
"x-ms-date": HttpDate.format(DateTime.now()),
"user-agent": userAgent,
"Cache-Control": "no-cache",
"Accept": "application/json",
"Host": _host,
"x-ms-documentdb-partitionkey": pKey == null ? "" : "[\"" + pKey_Filter + "\"]",
"x-ms-documentdb-query-enablecrosspartition": pKey == null ? "True" : ""
};
if(moreHeaders != null) {
headers.addAll(moreHeaders);
}
String strSELECT = "";
requiredColHeaders.forEach((col) {
strSELECT = strSELECT + "$azTblName[\"$col\"],";
});
strSELECT = strSELECT.substring(0, strSELECT.length - 1); // remove trailing ","
String strWHERE = "";
if(mapWHERE != null) {
mapWHERE.forEach((col, value) {
strWHERE = strWHERE + "($azTblName[\"$col\"] = \"$value\")AND";
});
strWHERE = strWHERE.substring(0, strWHERE.length - 3); // remove trailing "AND"
}
String strQuery = "SELECT $strSELECT FROM $azTblName";
if(strWHERE != "") {
strQuery = strQuery + " WHERE $strWHERE";
}
Map<String, dynamic> body = {
"query": strQuery,
"parameters": []
};
var response = await httpRequest(_collectionUrl + "/docs", headers, body, isQuery: true);
return response;
}
一切都在一起,还有生成授权令牌的功能:
import 'dart:convert';
import 'dart:io';
class azureCosmosHelper {
String masterKey = "<your_master_key>";
// Contains url to collection
String collectionUrl = "https://<your_database_account>.documents.azure.com/dbs/<your_database_id>/colls/<your_collection_id>";
String host = "<your_database_account>.documents.azure.com";
String pKey = "<your_partition_key>";
Future<void> getAzureDB() {
HttpClientResponse response = await doSELECTQuery("<userAgent>", List<String> tableColumns, "<tableName>",
pKey: this.pKey,
pKey_Filter: "<pKey_Filter>",
);
// parse response accordingly
}
Future<HttpClientResponse> doSELECTQuery(String userAgent, List<String> requiredColHeaders, String azTblName,
{Map<String,String> mapWHERE, String pKey, String pKey_Filter, Map<String, String> moreHeaders, String alternateCollectionUrl = null}) async {
String _collectionUrl;
String _host;
Uri uri = Uri.tryParse(alternateCollectionUrl);
if(uri != null) {
_host = uri.host;
}
_collectionUrl = alternateCollectionUrl;
} else {
_collectionUrl = this.collectionUrl;
_host = this.host;
}
String collectionPath = Uri.parse(_collectionUrl).path.substring(1); // remove leading "/"
Map<String, String> headers = {
"authorization": generateAuthToken(
"POST", "docs", collectionPath, HttpDate.format(DateTime.now()),
masterKey, "master"),
"x-ms-version": "2018-12-31",
"x-ms-date": HttpDate.format(DateTime.now()),
"user-agent": userAgent,
"Cache-Control": "no-cache",
"Accept": "application/json",
"Host": _host,
"x-ms-documentdb-partitionkey": pKey == null ? "" : "[\"" + pKey_Filter + "\"]",
"x-ms-documentdb-query-enablecrosspartition": pKey == null ? "True" : ""
};
if(moreHeaders != null) {
headers.addAll(moreHeaders);
}
String strSELECT = "";
requiredColHeaders.forEach((col) {
strSELECT = strSELECT + "$azTblName[\"$col\"],";
});
strSELECT = strSELECT.substring(0, strSELECT.length - 1); // remove trailing ","
String strWHERE = "";
if(mapWHERE != null) {
mapWHERE.forEach((col, value) {
strWHERE = strWHERE + "($azTblName[\"$col\"] = \"$value\")AND";
});
strWHERE = strWHERE.substring(0, strWHERE.length - 3); // remove trailing "AND"
}
String strQuery = "SELECT $strSELECT FROM $azTblName";
if(strWHERE != "") {
strQuery = strQuery + " WHERE $strWHERE";
}
Map<String, dynamic> body = {
"query": strQuery,
"parameters": []
};
var response = await httpRequest(_collectionUrl + "/docs", headers, body, isQuery: true);
return response;
}
Future<HttpClientResponse> httpRequest(String url, Map headers, Map body, {bool isQuery = false}) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
headers.forEach((key, value) {
request.headers.set(key,value);
});
if(isQuery) {
request.headers.set('content-type', 'application/query+json');
request.headers.set('x-ms-documentdb-isquery', 'True');
}
if(body != null) {
request.add(utf8.encode(json.encode(body)));
}
HttpClientResponse response = await request.close();
httpClient.close();
return response;
}
//Generates authorization token
String generateAuthToken(String verb, String resourceType, String resourceLink, String date, String key, String keyType, {String tokenVer="1.0"}) {
String payload=verb.toLowerCase()+"\n"
+resourceType.toLowerCase()+"\n"
+resourceLink+"\n"
+date.toLowerCase()+"\n"
+""+"\n";
var key_decode = base64.decode(key);
Hmac hmac = new Hmac(sha256, key_decode);
var messageBytes = utf8.encode(payload);
Digest digest = hmac.convert(messageBytes);
String signature = base64.encode(digest.bytes);
return Uri.encodeComponent("type="+keyType+"&ver="+tokenVer+"&sig="+signature);
}
}