使用 Google Vision API 请求 - 收到无效的 JSON 有效负载和 INVALID_ARGUMENT
request with Google Vision API - Invalid JSON payload received and INVALID_ARGUMENT
尝试按照 link 中的说明从我的 iOS 应用创建请求,但收到无效的 JSON 有效负载和 INVALID_ARGUMENT 错误消息。有什么建议吗?
这是我尝试使用的示例。
{
"requests":[
{
"image":{
"source":{
"imageUri":
"https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
}
},
"features":[
{
"type":"LOGO_DETECTION",
"maxResults":1
}
]
}
]
}
在我的 iOS 应用程序中,我创建了
let feature1 = ["type": "LOGO_DETECTION", "maxResults": 1] as [String : Any]
let features = [feature1]
let source = ["imageUri": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"]
let image = ["source": source]
let request = ["image": image, "features": features] as [String : Any]
let requests = ["requests": [request]]
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
let privateKey = "my............key"
let requestString = "https://vision.googleapis.com/v1/images:annotate?key=\(privateKey)"
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
switch response.result {
case .success(let data):
print("data", data)
print(response.result)
case .failure(let error):
print(error)
}
}
我可以看到我的打印日志中有同样的东西。
{
"requests" : [
{
"features" : [
{
"type" : "LOGO_DETECTION",
"maxResults" : 1
}
],
"image" : {
"source" : {
"imageUri" : "https:\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_272x92dp.png"
}
}
}
]
}
但是我收到以下错误信息
[BoringSSL] Function boringssl_context_get_peer_sct_list: line 1754 received sct extension length is less than sct data length
data {
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message."
},
{
"description": "Invalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message."
},
{
"description": "Invalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message."
}
]
}
]
}
}
正确答案
1.Remove
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
2.change
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
到
Alamofire.request(requestString, method: .post, parameters: requests, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response) in
乍一看,错误很明显:
- 未知名称
requests[][features][][maxResults]
: 无法绑定查询参数。在请求消息中找不到字段。
- 未知名称
requests[][image][source][imageUri]
: 无法绑定查询参数。在请求消息中找不到字段。
- 未知名称
requests[][features][][type]
: 无法绑定查询参数。在请求消息中找不到字段。"
但是将您的控制台输出与文档中的示例进行比较,它是匹配的。我的猜测是问题是两种可能性之一:
- 请求中完全缺少您的负载,或者
- 您没有正确编码负载。
为了在下次发生这种情况时为您提供帮助,我建议您通过构建有效负载并通过 Curl 或 Postman 发送它来进行调试,以消除您的应用程序的罪魁祸首。
获得有效负载后,将您的 Swift 应用指向 http://requestb.in,然后将您的请求发送到那里。这将允许您检查您发送的内容并将其与工作示例进行比较。
现在开始修复它:
原来问题是 #2 - 您没有正确编码。或者更确切地说,你是,但你没有发送编码字符串。
看到这一行:
let requests = ["requests": [request]]
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
然后你做:
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
请注意您是如何在有效负载中使用 requests
,而不是编码的 str
?您已将编码后的字符串隐藏在 if 语句中,使其无法使用。我会在这里使用 guard
- 它的代码更少,并且不会隐藏编码的字符串(它也更安全):
let requests = ["requests": [request]]
guard let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let encodedStr = String(data: data, encoding: .utf8) else { return }
Alamofire.request(requestString, method: .post, parameters: encodedStr).responseString { (response) in
// ^ use the right var here!
尝试按照 link 中的说明从我的 iOS 应用创建请求,但收到无效的 JSON 有效负载和 INVALID_ARGUMENT 错误消息。有什么建议吗?
这是我尝试使用的示例。
{
"requests":[
{
"image":{
"source":{
"imageUri":
"https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
}
},
"features":[
{
"type":"LOGO_DETECTION",
"maxResults":1
}
]
}
]
}
在我的 iOS 应用程序中,我创建了
let feature1 = ["type": "LOGO_DETECTION", "maxResults": 1] as [String : Any]
let features = [feature1]
let source = ["imageUri": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"]
let image = ["source": source]
let request = ["image": image, "features": features] as [String : Any]
let requests = ["requests": [request]]
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
let privateKey = "my............key"
let requestString = "https://vision.googleapis.com/v1/images:annotate?key=\(privateKey)"
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
switch response.result {
case .success(let data):
print("data", data)
print(response.result)
case .failure(let error):
print(error)
}
}
我可以看到我的打印日志中有同样的东西。
{
"requests" : [
{
"features" : [
{
"type" : "LOGO_DETECTION",
"maxResults" : 1
}
],
"image" : {
"source" : {
"imageUri" : "https:\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_272x92dp.png"
}
}
}
]
}
但是我收到以下错误信息
[BoringSSL] Function boringssl_context_get_peer_sct_list: line 1754 received sct extension length is less than sct data length
data {
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message."
},
{
"description": "Invalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message."
},
{
"description": "Invalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message."
}
]
}
]
}
}
正确答案
1.Remove
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
2.change
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
到
Alamofire.request(requestString, method: .post, parameters: requests, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response) in
乍一看,错误很明显:
- 未知名称
requests[][features][][maxResults]
: 无法绑定查询参数。在请求消息中找不到字段。 - 未知名称
requests[][image][source][imageUri]
: 无法绑定查询参数。在请求消息中找不到字段。 - 未知名称
requests[][features][][type]
: 无法绑定查询参数。在请求消息中找不到字段。"
但是将您的控制台输出与文档中的示例进行比较,它是匹配的。我的猜测是问题是两种可能性之一:
- 请求中完全缺少您的负载,或者
- 您没有正确编码负载。
为了在下次发生这种情况时为您提供帮助,我建议您通过构建有效负载并通过 Curl 或 Postman 发送它来进行调试,以消除您的应用程序的罪魁祸首。
获得有效负载后,将您的 Swift 应用指向 http://requestb.in,然后将您的请求发送到那里。这将允许您检查您发送的内容并将其与工作示例进行比较。
现在开始修复它:
原来问题是 #2 - 您没有正确编码。或者更确切地说,你是,但你没有发送编码字符串。
看到这一行:
let requests = ["requests": [request]]
if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
然后你做:
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
请注意您是如何在有效负载中使用 requests
,而不是编码的 str
?您已将编码后的字符串隐藏在 if 语句中,使其无法使用。我会在这里使用 guard
- 它的代码更少,并且不会隐藏编码的字符串(它也更安全):
let requests = ["requests": [request]]
guard let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
let encodedStr = String(data: data, encoding: .utf8) else { return }
Alamofire.request(requestString, method: .post, parameters: encodedStr).responseString { (response) in
// ^ use the right var here!