4

I have a simple Flask app like so:

import msgpack
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
  return render_template('index.html')

@app.route('/test')
def test():
    return msgpack.packb([1, 2, 3])

@app.route('/ping')
def ping():
    return "Pong"

if __name__ == '__main__':
    app.run(debug=True, port=5000)

In the Flask route /test, I'm using msgpack to pack an array which is returned as a response. When this response is printed to the console, it looks something like this: b'\x93\x01\x02\x03'

I'm using AngularJS 1.7 in my front end which looks like:

<!doctype html>
<html ng-app="MyApp">
  <body ng-cloak>
    <div class="container" ng-controller="MyController">
      <h1>Hello, {{text}}</h1>
      <button class="btn btn-primary" ng-click="ping()">Ping</button>
      <button class="btn btn-primary" ng-click="getMsgpackData()">Get Msgpack Data</button>
    </div>

    <script src="jquery-3.3.1.slim.min.js"></script>
    <script src="/angular.js/1.7.2/angular.min.js"></script>
    <script src="https://rawgithub.com/kawanet/msgpack-lite/master/dist/msgpack.min.js"></script>
    <script>
      var myApp = angular.module("MyApp", []);

      myApp.controller("MyController", ["$scope", "$http", function($scope, $http) {
        $scope.text = "World";

        $scope.ping = function() {
          $http.get("/ping").then(function success(response) {
              $scope.text = response.data;
          }, function error(response) {
              console.log(response);
          });
        }

        $scope.getMsgpackData = function() {
          $http.get("/test").then(function success(response) {
              console.log(response);
              $scope.text = msgpack.decode(response.data);
          }, function error(response) {
              console.log(response);
          });
        }
      }]);
    </script>
  </body>
</html>

When the getMsgpackData function is invoked in MyController, I get the following error in the browser's console:

Error: Invalid type: 0x�
    at n.r [as decode] (msgpack.min.js:1)
    at n.fetch (msgpack.min.js:1)
    at n.s [as read] (msgpack.min.js:1)
    at Object.n [as decode] (msgpack.min.js:1)
    at success ((index):46)
    at angular.js:17396
    at m.$digest (angular.js:18557)
    at m.$apply (angular.js:18945)
    at k (angular.js:12799)
    at V (angular.js:13056) "Possibly unhandled rejection: {}" 

It seems like the first HEX value \x93 is not being decoded.

I'm using kawanet/msgpack-lite in the front end as I found that it can be used in a browser.

Please help!

codemaniac
  • 879
  • 1
  • 11
  • 31

1 Answers1

4

The error message tells you you sent the wrong type of object to the decode() method. The buffer decoding documentation shows that only buffers, arrays and Uint8Array objects are supported.

Change the response type to arraybuffer (from the default text), then feed the response data to msgpack.decode() as a Uint8Array typed array:

$http.get("/test", {responseType: "arraybuffer"}).then(function success(response) {
    var arr = new Uint8Array(response.data);
    console.log(arr);
    $scope.text = msgpack.decode(arr);
}, function error(response) {
    console.log(response);
});

While not necessary here, you do want to set a different content type on your Flask response. Currently the /test route is advertising the content as text/html, while you really should be labelling as application/msgpack:

@app.route('/test')
def test():
    return msgpack.packb([1, 2, 3]), {'content-type': 'application/msgpack'}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343