在 Flask 和 AngularJS 中使用 Msgpack 时出现无效类型错误
Invalid Type Error while using Msgpack with Flask and AngularJS
我有一个像这样的简单 Flask 应用程序:
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)
在 Flask 路由 /test
中,我使用 msgpack 打包一个数组,该数组作为响应返回。当此响应打印到控制台时,它看起来像这样:b'\x93\x01\x02\x03'
我在我的前端使用 AngularJS 1.7,它看起来像:
<!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>
当在 MyController
中调用 getMsgpackData
函数时,我在浏览器的控制台中收到以下错误:
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: {}"
第一个 HEX 值 \x93
似乎没有被解码。
我在前端使用 kawanet/msgpack-lite,因为我发现它可以在浏览器中使用。
请帮忙!
错误消息告诉您您向 decode()
方法发送了错误类型的对象。 buffer decoding documentation 表明仅支持缓冲区、数组和 Uint8Array
对象。
将响应类型更改为 arraybuffer
(从默认的 text
),然后将响应数据作为 Uint8Array
类型数组提供给 msgpack.decode()
:
$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);
});
虽然这里没有必要,但您确实希望在 Flask 响应中设置不同的内容类型。当前 /test
路由将内容通告为 text/html
,而您实际上应该将其标记为 application/msgpack
:
@app.route('/test')
def test():
return msgpack.packb([1, 2, 3]), {'content-type': 'application/msgpack'}
我有一个像这样的简单 Flask 应用程序:
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)
在 Flask 路由 /test
中,我使用 msgpack 打包一个数组,该数组作为响应返回。当此响应打印到控制台时,它看起来像这样:b'\x93\x01\x02\x03'
我在我的前端使用 AngularJS 1.7,它看起来像:
<!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>
当在 MyController
中调用 getMsgpackData
函数时,我在浏览器的控制台中收到以下错误:
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: {}"
第一个 HEX 值 \x93
似乎没有被解码。
我在前端使用 kawanet/msgpack-lite,因为我发现它可以在浏览器中使用。
请帮忙!
错误消息告诉您您向 decode()
方法发送了错误类型的对象。 buffer decoding documentation 表明仅支持缓冲区、数组和 Uint8Array
对象。
将响应类型更改为 arraybuffer
(从默认的 text
),然后将响应数据作为 Uint8Array
类型数组提供给 msgpack.decode()
:
$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);
});
虽然这里没有必要,但您确实希望在 Flask 响应中设置不同的内容类型。当前 /test
路由将内容通告为 text/html
,而您实际上应该将其标记为 application/msgpack
:
@app.route('/test')
def test():
return msgpack.packb([1, 2, 3]), {'content-type': 'application/msgpack'}