JSON中的Big Integer被Angular破坏而不是被CURL破坏?

Saq*_*Ali 6 python django rest json angularjs

我使用Django Rest Framework创建了一个Django REST API .

我使用3个不同的客户来点击这个应用程序:

  • 卷曲(用于调试目的)
  • Swagger接口(用于调试目的)
  • 我的Angular应用程序

我有一个令人困惑的问题,即API返回的数据被Swagger和Angular损坏,而不是被Curl破坏.

我的Django模型看起来像这样:

class MyModel1(CachingMixin, models.Model):
    id = models.BigIntegerField(default=make_id, primary_key=True)
    name = models.CharField(max_length=50, null=False, blank=False,)
Run Code Online (Sandbox Code Playgroud)

这里make_id()描述上面引用的方法.我最近从标准的Django分配和自动递增的主键实现了这一变化.作为改变的一部分,我将id从IntegerFielda 转换为a BigIntegerField.

我有一些其他Django视图代码(我在这里没有显示)创建一个名为的端点GetMyModel1ByName.该端点返回一个序列化的实例MyModel1.这是卷曲,显示当我点击该端点时会发生什么.它完美地运作:

$ curl http://localhost:4212/api/getMyModel1ByName/?name=my-name
{"id": 10150133855458395, "name": "my-name"}
Run Code Online (Sandbox Code Playgroud)

现在,当我从Chrome的开发者控制台访问同一个端点时会发生什么:

> $http = angular.element(document.body).injector().get('$http');
> $http.get("http://localhost:4212/api/getMyModel1ByName/?name=my-name").then(function(response) { console.log(JSON.stringify(response.data)) }).catch(function (error) { console.log(error.data) });
{"id":10150133855458396, "name":"my-name"}
Run Code Online (Sandbox Code Playgroud)

正如您所见,curl将ID报告为10150133855458395.这是正确的.这就是数据库中的内容.但Angular将其报告为1015013385545839 6.最后的数字是错误的.差异是1.这是非常令人惊讶的!

这是一个真正令人困惑的错误.我的Django代码非常简单,我非常有信心它没有错误.相反,我觉得这个改变id从外地IntegerFieldBigIntegerField可能导致此问题.为什么会这样,解决方案是什么?它破坏了我的应用程序的功能.当我通过Swagger点击此端点时,我看到同样的损坏.

编辑:另一个提问者遇到了同样的问题.很高兴知道我不是唯一一个!但是,这个问题的答案并不是真正的答案.他们没有解释原因.他们没有告诉我如何在Angular JS代码中解决问题.

Yev*_*lev 5

您正在尝试存储一个大于安全最大javascript整数的数字value(+/- 9007199254740991).

您的make_id生成器应返回与javascript限制相关的值.

欲了解更多信息,请阅读:http: //blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

  • curl是您可以信任的唯一来源.所有浏览器表示都可以使用javascript. (2认同)

e4c*_*4c5 4

总长DR

长话短说。让您的视图以字符串形式返回响应。

{"id": "10150133855458395", "name": "我的名字"}

长话短说

让我们缩小范围。事实上,你可以而且应该在没有 django 参与的情况下测试它。请将您获取的 json 保存curl http://localhost:4212/api/getMyModel1ByName/?name=my-name到 django 项目的 /static/ 文件夹中。现在,当你获取它时,django 不再参与图片。您甚至可以将此文件托管在其他类型的服务器上。我们称之为 hello.json

现在如果你输入http://localhost:4212/static/hello.json你应该得到。

{"id": 10150133855458395, "name": "my-name"}
Run Code Online (Sandbox Code Playgroud)

更新:

如果您没有正确看到 JSON 数据,则意味着您遇到了第一条评论中的问答中描述的问题。您有一个狡猾的扩展,它弄乱了 JSON。禁用所有扩展并重试。让它们一一回归。

现在让我们创建一个小的角度脚本。

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

  <div ng-app="myApp" ng-controller="myCtrl">

    <h1>{{myjson}}</h1>

  </div>


<script>
   var app = angular.module('myApp', []);
   app.controller('myCtrl', function($scope, $http) {
   $http.get("/static/hello.json")
     .then(function(response) {
        console.log(response.data)
        $scope.myjson = response.data;
      });
   });
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

然后将其保存angular.html在静态文件夹中,您可以将其加载到浏览器中,如http://localhost:4212/static/angular.html所示。

{"id":10150133855458396,"name":"my-name"}
Run Code Online (Sandbox Code Playgroud)

这绝对不是正确的结果。然而这里没有BigIntegerField,也没有 django。问题完全出在浏览器和角度上。我们已经成功缩小了问题范围。正如您从浏览器检索到的响应中看到的那样,它完全在角度范围内。

Chrome 开发工具显示已检索到正确的 JSON

Angular 因大量数据而令人窒息。相反,将它们作为字符串发送。