gpt4 book ai didi

rest - Http.post 在flutter/dart 中不接受内容类型application/query+json

转载 作者:行者123 更新时间:2023-12-03 03:22:43 33 4
gpt4 key购买 nike

我正在使用颤振应用程序与 azure cosmos db 交谈。 cosmos db 有一个基于 sql 查询的 rest api。其中内容类型应为 application/query+json。
我尝试使用 postman 连接到 cosmos db 它工作但在颤动中我遇到了一个异常

Bad state: Cannot set the body fields of a Request with content-type "application/query+json"

以下是示例 http.post 代码:
final http.Response response =
await http.post(
url,
headers: {<other headers>, 'Content-Type' : 'application/query+json'},
body: {
"query" : "<SQL Query>",
"parameters" : [<parameter name and value pairs>]
},
);

我已经在 postman 中对此进行了测试,并且它按预期工作。

如果 http:dart 包支持正文的内容类型 application/query+json,我应该如何制定我的请求正文。

最佳答案

尝试使用 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;
}

请注意,您需要逐个设置标题。

一个只做 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;
}

一切都在一起,以及生成授权 token 的功能:
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);
}
}

关于rest - Http.post 在flutter/dart 中不接受内容类型application/query+json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61501765/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com