Getting `Status Code:400 Bad Request` When calling Microsoft Azure Emotion API with data of type `Content-Type:application/octet-stream`
Asked Answered
T

1

0

I'm trying to send data to Microsoft Cognitive Services' Emotion API, in the form of Content-Type: application/octet-stream.

I'm getting the Base64 string of an image from a canvas by calling canvas.toDataURL('image/jpeg', 0.1);(I've tried calling it with 1, 0.5, 0.2 as well, just to check whether it works and stops giving me errors)

Then with that Base64 string, I'm calling the EmotionService's getUserEmotion method.

I followed the instructions mentioned in this answer, to make an AJAX call using Angular's HttpClient. Here's what my service looks like:

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 });
  }

}

Here's what my Network Tab Looks Like for the request:

enter image description here

Follwing are the questions that I have:

  1. In the SO Answer that I'm following, they've also specified that I should set the processData:false option for my AJAX call. But I'm not sure how to do that using Angular's HttpClient.
  2. The data field in the request payload is also coming as empty. But when I debugged, I was getting proper Blob Object from the makeBlob method. Why is that happening?
Toplofty answered 23/11, 2017 at 19:5 Comment(0)
T
1

I was doing a very silly thing here. The API Documentation of the Emotion API here says that it needs data as binary image data.

API DOC of Emotion API

But I was still giving it as JSON. I simply changed the implementation of getUserEmotion method. Instead of

return this.http.post(this.apiUrl, { "data": this.makeBlob(userImageBlob) }, { headers: headers });

I used this

return this.http.post(this.apiUrl, this.makeBlob(userImageBlob), { headers: headers });

Hope this helps someone who's facing the same issue!

Toplofty answered 23/11, 2017 at 19:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.