【问题标题】:Can not consume my Django Rest Framework API with Ajax无法使用 Ajax 使用我的 Django Rest Framework API
【发布时间】:2017-10-30 20:37:21
【问题描述】:

我在 Django Rest 框架中编写了一个简单的视图,并在 Web 浏览器中对其进行了测试:

@api_view(['Get', 'Post'])
@permission_classes((AllowAny,))
@method_decorator(csrf_exempt, name='dispatch')
def hello_world(request):
    print(request.data)
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    return Response({"id":201,"content":"Hello, World!"})

并尝试通过 Ajax 使用它,使用 jQuery 和 AngularJs。

jQuery

对于 jQuery,我使用以下代码:

                $.ajax({
                    type: "POST",
                    dataType: "json",
                    ContentType: "application/json",
                    url: "http://127.0.0.1:8000/test/",
                    "data": data,
                    success: function(inp_data, status, jqXHR){
                        console.log('success');
                        console.log(JSON.stringify(inp_data));
                        },
                    error: function(xhr, errMsg) {
                        console.log('failure');
                        console.log(errMsg);
                        console.log(xhr.status + ": " + xhr.responseText);
                        }
                    }); 

并接收:

1) 在后端:

<QueryDict: {'key1': ['value1']}>
[26/Oct/2017 11:20:34] "POST /test/ HTTP/1.1" 200 15

2) 在前端控制台中:

failure (11:20:35:881 | null)
  at public_html/index.html:132
error (11:20:35:887 | null)
  at public_html/index.html:133
0: undefined (11:20:35:888 | null)
  at public_html/index.html:134

因此,使用 jQuery,我可以将数据从前端发送到后端,但以相反的方式发送数据很麻烦。

AngularJs

我尝试使用以下 html 代码发出 get 请求:

<html ng-app="demo">
    <head>
        <title>Hello AngularJS</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
        <script src="hello.js"></script>
    </head>

    <body>
        <div ng-controller="Hello">
            <p>The ID is {{greeting.id}}</p>
            <p>The content is {{greeting.content}}</p>
        </div>
    </body>
</html>

和js:

angular.module('demo', [])
.controller('Hello', function($scope, $http) {
    console.log('wait for response');
    $http.get('http://127.0.0.1:8000/test/').
        then(function(response) {
            console.log('get response');
            $scope.greeting = response.data;
        });
    console.log('finished');
});

运行上面的代码后,我收到:

1)在后端:

<QueryDict: {}>
[26/Oct/2017 12:33:06] "GET /test/ HTTP/1.1" 200 36

2)在前端控制台中:

wait for response (12:33:06:150 | null)
  at public_html/hello.js:8
finished (12:33:06:163 | null)
  at public_html/hello.js:14

那么为什么我无法在展位 jQuery 和 AngularJS 中收到我的 DRF 响应?

更新

在 chrome 的控制台中找到它:

XMLHttpRequest cannot load http://127.0.0.1:8000/test. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8383' is therefore not allowed access.
:8383/favicon.ico Failed to load resource: net::ERR_EMPTY_RESPONSE

当我通过 Django(使用 {% verbatim %})而不是 NetBeans(我喜欢用它来编写前端)呈现 AngularJs 代码时,它工作得很好。因此,如果我不想让 Django Rest Framework 与 NetBeans IDE 交朋友,我应该启用 CORS。

【问题讨论】:

  • Django返回的响应是什么样子的?
  • 如果我在终端输入:$ curl 127.0.0.1:8000/test 它返回:{"content":"Hello, World!","id":201} 在同一个终端所以无论如何服务器都会发出响应跨度>
  • JS 控制台有错误吗? Django 中是否启用了 CORS?
  • 另外,你是否 100% 肯定 localhost127.0.0.1 在你的机器上是同一个东西?也许尝试以0.0.0.0 8000 的方式运行 Django。

标签: jquery angularjs ajax rest django-rest-framework


【解决方案1】:

问题在于处理我从 NetBeans 运行前端的事实。 NetBeans 的控制台非常好,但 chrome 的控制台让我了解了 CORS 冲突。我不知道为什么 django 的输出中没有显示 CORS-conflict,但是当我根据官方 docs 安装“django-cors-headers”并设置时:

CORS_ORIGIN_ALLOW_ALL=True

在我的 settings.py 中,它开始工作了!!!

【讨论】:

    【解决方案2】:

    在 django rest 框架请求中,request.data 中不存在 GET 参数。它们是查询参数而不是数据。所以它们被放在request.query_params 下。从get request中的request.query_params访问数据

    see the doc

    试试这个来获取 POST 和 GET 数据

    @api_view(['Get', 'Post'])
    @permission_classes((AllowAny,))
    @method_decorator(csrf_exempt, name='dispatch')
    def hello_world(request):
        if request.method == 'POST':
            print(request.data)
            return Response({"message": "Got some data in POST!", "data": request.data})
        if request.method == 'GET':
            print(request.query_params)
            return Response({"message": "Got some data in GET!", "data": request.query_params})
        return Response({"detail":"Invalid request type"}, status=400)
    

    【讨论】:

    • 我已经写过我发送数据到服务器没有问题。前端接收数据有问题,部分解决(见UPD)。
    • 你是说你在服务器端接收数据,在前端看不到响应。对吧?如果是这样,请分享您的回复。显示你的控制台输出。
    猜你喜欢
    • 2021-04-06
    • 2018-12-20
    • 2017-05-13
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多