使用“Content-Type:application/octet-stream”类型的数据调用 Microsoft Azure Emotion API 时获取“Status Code:400 Bad Request”
Getting `Status Code:400 Bad Request` When calling Microsoft Azure Emotion API with data of type `Content-Type:application/octet-stream`
我正在尝试以 Content-Type: application/octet-stream
的形式向 Microsoft Cognitive Services' Emotion API 发送数据。
我通过调用 canvas.toDataURL('image/jpeg', 0.1);
从 canvas 获取图像的 Base64 字符串(我也尝试用 1、0.5、0.2 调用它,只是为了检查它是否工作并停止给我错误)
然后使用该 Base64 字符串,我正在调用 EmotionService 的 getUserEmotion
方法。
我按照 中提到的说明使用 Angular 的 HttpClient 进行了 AJAX 调用。这是我的服务的样子:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable()
export class EmotionService {
apiUrl: string = 'https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize';
constructor(private http: HttpClient) {}
getUserEmotion(userImageBlob) {
let headers = new HttpHeaders();
headers = headers.set('Ocp-Apim-Subscription-Key', 'my-api-key-here');
headers = headers.set('Content-Type', 'application/octet-stream');
return this.http.post(this.apiUrl, { "data": this.makeBlob(userImageBlob) }, { headers: headers });
}
makeBlob(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], { type: contentType });
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
}
这是我的网络选项卡针对请求的样子:
以下是我的问题:
- 在我关注的 SO Answer 中,他们还指定我应该为我的 AJAX 调用设置
processData:false
选项。但我不确定如何使用 Angular 的 HttpClient
。
- 请求负载中的
data
字段也为空。但是当我调试时,我从 makeBlob
方法中获得了正确的 Blob 对象。为什么会这样?
我在这里做了一件非常愚蠢的事情。这里的 API Documentation of the Emotion API 表示它需要数据作为二进制图像数据。
但我仍然给它 JSON。我只是更改了 getUserEmotion
方法的实现。而不是
return this.http.post(this.apiUrl, { "data": this.makeBlob(userImageBlob) }, { headers: headers });
我用过这个
return this.http.post(this.apiUrl, this.makeBlob(userImageBlob), { headers: headers });
希望这对遇到同样问题的人有所帮助!
我正在尝试以 Content-Type: application/octet-stream
的形式向 Microsoft Cognitive Services' Emotion API 发送数据。
我通过调用 canvas.toDataURL('image/jpeg', 0.1);
从 canvas 获取图像的 Base64 字符串(我也尝试用 1、0.5、0.2 调用它,只是为了检查它是否工作并停止给我错误)
然后使用该 Base64 字符串,我正在调用 EmotionService 的 getUserEmotion
方法。
我按照
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable()
export class EmotionService {
apiUrl: string = 'https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize';
constructor(private http: HttpClient) {}
getUserEmotion(userImageBlob) {
let headers = new HttpHeaders();
headers = headers.set('Ocp-Apim-Subscription-Key', 'my-api-key-here');
headers = headers.set('Content-Type', 'application/octet-stream');
return this.http.post(this.apiUrl, { "data": this.makeBlob(userImageBlob) }, { headers: headers });
}
makeBlob(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], { type: contentType });
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
}
这是我的网络选项卡针对请求的样子:
以下是我的问题:
- 在我关注的 SO Answer 中,他们还指定我应该为我的 AJAX 调用设置
processData:false
选项。但我不确定如何使用 Angular 的HttpClient
。 - 请求负载中的
data
字段也为空。但是当我调试时,我从makeBlob
方法中获得了正确的 Blob 对象。为什么会这样?
我在这里做了一件非常愚蠢的事情。这里的 API Documentation of the Emotion API 表示它需要数据作为二进制图像数据。
但我仍然给它 JSON。我只是更改了 getUserEmotion
方法的实现。而不是
return this.http.post(this.apiUrl, { "data": this.makeBlob(userImageBlob) }, { headers: headers });
我用过这个
return this.http.post(this.apiUrl, this.makeBlob(userImageBlob), { headers: headers });
希望这对遇到同样问题的人有所帮助!