Django的is

编程入门 行业动态 更新时间:2024-10-14 14:20:56
Django的is_ajax()请求在开发过程中工作,但由于“未定义responseJSON”而导致生产中断(Django's is_ajax() request works during development but breaks in production due to “undefined responseJSON”)

在开发过程中,我有一个可以工作的ajax方法 - 它执行,发布到后端,我的Django视图检查is_ajax() ,然后return JsonResponse() 。

回到前端,我深入了解responseJSON以获取我的对象。

在生产环境中,显然没有responseJSON 。

为什么?

这是我的ajax方法:

$(document).ready(function(){ var $myForm = $('.ajax-public-toggle-form') $myForm.change(function(event){ var $formData = $(this).serialize() var $endpoint = $myForm.attr('data-url') $.ajax({ method: "POST", url: $endpoint, data: $formData, success: handleFormSuccess, error: handleFormError, }) }) function handleFormSuccess(data, textStatus, jqXHR){ // no need to do anything here console.log(data) console.log(textStatus) console.log(jqXHR) } function handleFormError(jqXHR, textStatus, errorThrown){ // on error, reset form. raise validationerror $('#public_toggle_form_errors').text(jqXHR["responseJSON"]["public"]); $('#public_toggle_form_errors').show(); console.log(jqXHR) console.log(textStatus) console.log(errorThrown) $myForm[0].reset(); // reset form data // console.log(errors) } })

所以我仍然可以使用console.log(jqxhr),但它不会像开发时那样包含responseJSON对象。

这是Django视图:

class AjaxView(View): def post(self, request): if self.request.is_ajax(): if self.request.user.is_authenticated(): if self.request.user.profile.public: data = { 'message': "Allow button click" } return JsonResponse(data) else: data = { 'error': "ERRO HERE", 'message': "EORR MESG" } return JsonResponse(data, status=400) else: data = { 'message': "LOG IN" } return JsonResponse(data, status=400)

控制台将首先输出:

jquery-3.3.1.min.js:2 POST https://paira.herokuapp.com/profile/public_toggle 403 (Forbidden)

然后:

project.js:52 Uncaught TypeError: Cannot read property 'public' of undefined at Object.handleFormError [as error]

'公共'指的是:

function handleFormError(jqXHR, textStatus, errorThrown){ // on error, reset form. raise validationerror $('#public_toggle_form_errors').text(jqXHR["responseJSON"]["public"]);

实际的jqXHR响应会有如下所示:

{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …} abort : ƒ (e) always : ƒ () catch : ƒ (e) done : ƒ () fail : ƒ () getAllResponseHeaders : ƒ () getResponseHeader : ƒ (e) overrideMimeType : ƒ (e) pipe : ƒ () progress : ƒ () promise : ƒ (e) readyState : 4 responseText : "<!DOCTYPE html>↵↵↵<html lang="en" class="fontawesome-i2svg-pending">↵↵ <head>↵ <meta charset="utf-8">↵ <meta http-equiv="x-ua-compatible" content="ie=edge">↵ <title>Forbidden (403)</title>↵ <meta name="viewport" content="width=device-width, initial-scale=1.0">↵ <meta name="description" content="">↵ <meta name="author" content="">↵ <link href="https://fonts.googleapis.com/css?family=Open+Sans|Raleway" rel="stylesheet">↵↵↵ <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->↵ <!--[if lt IE 9]>↵ <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>↵ <![endif]-->↵↵ ↵ <!-- Latest compiled and minified Bootstrap 4 beta CSS -->↵ ↵ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">↵↵↵ <!-- Your stuff: Third-party CSS libraries go here -->↵ <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />↵↵↵ <!-- This file stores project-specific CSS -->↵ <link href="/static/css/main.css" rel="stylesheet">↵ ↵ ↵↵ ↵↵ </head>↵↵ <body>↵ ↵↵↵<div class="">↵ <nav class="navbar fixed-top navbar-expand-md navbar-light bg-light">↵ <a class="navbar-brand ml-3" href="/">Parup</a>↵ <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">↵ <span class="navbar-toggler-icon"></span>↵ </button>↵↵↵ <div class="collapse navbar-collapse" id="navbarSupportedContent">↵ <ul class="navbar-nav ml-auto mr-5 align-items-center">↵↵ ↵ <li class="nav-item">↵ <a id="sign-up-link" class="nav-link" href="/accounts/signup/">Sign Up</a>↵ </li>↵ <li class="nav-item">↵ <a id="log-in-link" class="nav-link" href="/accounts/login/">Sign In</a>↵ </li>↵ ↵ </ul>↵ </div>↵ </nav>↵↵</div>↵↵ <div class="container pt-5 mt-5 mb-5">↵↵ ↵↵ ↵<h1>Forbidden (403)</h1>↵↵<p>CSRF verification failed. Request aborted.</p>↵↵↵↵ </div> <!-- /container -->↵↵ ↵ <div class="container-fluid footer mt-5 mb-2">↵ ↵<hr class="col-md-2" />↵<div class="row">↵ <div class="col-md-12">↵ I am the footer now↵↵ </div>↵</div>↵<div class="row h-100 footer-links">↵ <div class="col-md-12">↵ <p>ABOUT&nbsp&nbspCONTACT&nbsp&nbspTERMS&nbsp&nbspPRIVACY&nbsp&nbspBLOG</p>↵ </div>↵</div>↵ </div>↵ ↵ ↵↵ <!-- Le javascript↵ ================================================== -->↵ <!-- Placed at the end of the document so the pages load faster -->↵↵ ↵↵↵<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>↵<script src="/static/js/jquery-3.3.1.min.js"></script>↵<!-- Required by Bootstrap v4 beta -->↵<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwApKaMNFNmj4" crossorigin="anonymous"></script>↵<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>↵↵<!-- Your stuff: Third-party javascript libraries go here -->↵↵↵<script src="/static/js/fontawesome-all.js"></script>↵<script src="/static/js/reconnecting-websocket.min.js"></script>↵<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/fileinput.min.js"></script>↵↵↵↵↵↵↵<script src="/static/notifications/notify.js"></script>↵↵<script>↵ notify_badge_class='live_notify_badge';↵ notify_menu_class='live_notify_list';↵ notify_api_url='/inbox/notifications/api/unread_list/';↵ notify_fetch_count='10';↵ notify_unread_url='/inbox/notifications/unread/';↵ notify_mark_all_unread_url='/inbox/notifications/mark-all-as-read/';↵ notify_refresh_period=5000;↵ register_notifier(fill_notification_list);register_notifier( fill_notification_badge);</script>↵↵<!-- place project specific Javascript in this file -->↵<script src="/static/js/project.js"></script>↵↵<script src="/static/js/main.js"></script>↵↵↵↵<script type="text/javascript">↵ function getCookie(name) {↵ var cookieValue = null;↵ if (document.cookie && document.cookie !== '') {↵ var cookies = document.cookie.split(';');↵ for (var i = 0; i < cookies.length; i++) {↵ var cookie = jQuery.trim(cookies[i]);↵ // Does this cookie string begin with the name we want?↵ if (cookie.substring(0, name.length + 1) === (name + '=')) {↵ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));↵ break;↵ }↵ }↵ }↵ return cookieValue;↵ }↵↵ var csrftoken = getCookie('csrftoken');↵↵ function csrfSafeMethod(method) {↵ // these HTTP methods do not require CSRF protection↵ return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));↵ }↵ $.ajaxSetup({↵ beforeSend: function(xhr, settings) {↵ if (!csrfSafeMethod(settings.type) && !this.crossDomain) {↵ xhr.setRequestHeader("X-CSRFToken", csrftoken);↵ }↵ }↵ });↵</script>↵↵↵ ↵ ↵ </body>↵</html>↵↵" setRequestHeader : ƒ (e,t) state : ƒ () status : 403 statusCode : ƒ (e) statusText : "Forbidden" then : ƒ (t,r,i) __proto__ : Object

编辑:我在js.html中像这样分别发送CSRF:

{# CSRF #} <script type="text/javascript"> function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); </script> <!-- place project specific Javascript in this file --> <script src="{% static 'js/project.js' %}"></script>

我最初的AJAX代码是在project.js中。 脚本文件在后面。

During development, I have an ajax method that works--it executes, posts to the backend, my Django view checks if is_ajax(), then return JsonResponse().

Back on the frontend, I dig into responseJSON to get my object.

In a production environment, there is apparently no responseJSON.

Why?

Here's my ajax method:

$(document).ready(function(){ var $myForm = $('.ajax-public-toggle-form') $myForm.change(function(event){ var $formData = $(this).serialize() var $endpoint = $myForm.attr('data-url') $.ajax({ method: "POST", url: $endpoint, data: $formData, success: handleFormSuccess, error: handleFormError, }) }) function handleFormSuccess(data, textStatus, jqXHR){ // no need to do anything here console.log(data) console.log(textStatus) console.log(jqXHR) } function handleFormError(jqXHR, textStatus, errorThrown){ // on error, reset form. raise validationerror $('#public_toggle_form_errors').text(jqXHR["responseJSON"]["public"]); $('#public_toggle_form_errors').show(); console.log(jqXHR) console.log(textStatus) console.log(errorThrown) $myForm[0].reset(); // reset form data // console.log(errors) } })

So I can still console.log(jqxhr) but it won't include the responseJSON object like it does during development.

This is the Django view:

class AjaxView(View): def post(self, request): if self.request.is_ajax(): if self.request.user.is_authenticated(): if self.request.user.profile.public: data = { 'message': "Allow button click" } return JsonResponse(data) else: data = { 'error': "ERRO HERE", 'message': "EORR MESG" } return JsonResponse(data, status=400) else: data = { 'message': "LOG IN" } return JsonResponse(data, status=400)

The console will first output:

jquery-3.3.1.min.js:2 POST https://paira.herokuapp.com/profile/public_toggle 403 (Forbidden)

then:

project.js:52 Uncaught TypeError: Cannot read property 'public' of undefined at Object.handleFormError [as error]

'public' referring to:

function handleFormError(jqXHR, textStatus, errorThrown){ // on error, reset form. raise validationerror $('#public_toggle_form_errors').text(jqXHR["responseJSON"]["public"]);

The actual jqXHR response will have something like:

{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …} abort : ƒ (e) always : ƒ () catch : ƒ (e) done : ƒ () fail : ƒ () getAllResponseHeaders : ƒ () getResponseHeader : ƒ (e) overrideMimeType : ƒ (e) pipe : ƒ () progress : ƒ () promise : ƒ (e) readyState : 4 responseText : "<!DOCTYPE html>↵↵↵<html lang="en" class="fontawesome-i2svg-pending">↵↵ <head>↵ <meta charset="utf-8">↵ <meta http-equiv="x-ua-compatible" content="ie=edge">↵ <title>Forbidden (403)</title>↵ <meta name="viewport" content="width=device-width, initial-scale=1.0">↵ <meta name="description" content="">↵ <meta name="author" content="">↵ <link href="https://fonts.googleapis.com/css?family=Open+Sans|Raleway" rel="stylesheet">↵↵↵ <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->↵ <!--[if lt IE 9]>↵ <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>↵ <![endif]-->↵↵ ↵ <!-- Latest compiled and minified Bootstrap 4 beta CSS -->↵ ↵ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">↵↵↵ <!-- Your stuff: Third-party CSS libraries go here -->↵ <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />↵↵↵ <!-- This file stores project-specific CSS -->↵ <link href="/static/css/main.css" rel="stylesheet">↵ ↵ ↵↵ ↵↵ </head>↵↵ <body>↵ ↵↵↵<div class="">↵ <nav class="navbar fixed-top navbar-expand-md navbar-light bg-light">↵ <a class="navbar-brand ml-3" href="/">Parup</a>↵ <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">↵ <span class="navbar-toggler-icon"></span>↵ </button>↵↵↵ <div class="collapse navbar-collapse" id="navbarSupportedContent">↵ <ul class="navbar-nav ml-auto mr-5 align-items-center">↵↵ ↵ <li class="nav-item">↵ <a id="sign-up-link" class="nav-link" href="/accounts/signup/">Sign Up</a>↵ </li>↵ <li class="nav-item">↵ <a id="log-in-link" class="nav-link" href="/accounts/login/">Sign In</a>↵ </li>↵ ↵ </ul>↵ </div>↵ </nav>↵↵</div>↵↵ <div class="container pt-5 mt-5 mb-5">↵↵ ↵↵ ↵<h1>Forbidden (403)</h1>↵↵<p>CSRF verification failed. Request aborted.</p>↵↵↵↵ </div> <!-- /container -->↵↵ ↵ <div class="container-fluid footer mt-5 mb-2">↵ ↵<hr class="col-md-2" />↵<div class="row">↵ <div class="col-md-12">↵ I am the footer now↵↵ </div>↵</div>↵<div class="row h-100 footer-links">↵ <div class="col-md-12">↵ <p>ABOUT&nbsp&nbspCONTACT&nbsp&nbspTERMS&nbsp&nbspPRIVACY&nbsp&nbspBLOG</p>↵ </div>↵</div>↵ </div>↵ ↵ ↵↵ <!-- Le javascript↵ ================================================== -->↵ <!-- Placed at the end of the document so the pages load faster -->↵↵ ↵↵↵<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>↵<script src="/static/js/jquery-3.3.1.min.js"></script>↵<!-- Required by Bootstrap v4 beta -->↵<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwApKaMNFNmj4" crossorigin="anonymous"></script>↵<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>↵↵<!-- Your stuff: Third-party javascript libraries go here -->↵↵↵<script src="/static/js/fontawesome-all.js"></script>↵<script src="/static/js/reconnecting-websocket.min.js"></script>↵<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.5/js/fileinput.min.js"></script>↵↵↵↵↵↵↵<script src="/static/notifications/notify.js"></script>↵↵<script>↵ notify_badge_class='live_notify_badge';↵ notify_menu_class='live_notify_list';↵ notify_api_url='/inbox/notifications/api/unread_list/';↵ notify_fetch_count='10';↵ notify_unread_url='/inbox/notifications/unread/';↵ notify_mark_all_unread_url='/inbox/notifications/mark-all-as-read/';↵ notify_refresh_period=5000;↵ register_notifier(fill_notification_list);register_notifier( fill_notification_badge);</script>↵↵<!-- place project specific Javascript in this file -->↵<script src="/static/js/project.js"></script>↵↵<script src="/static/js/main.js"></script>↵↵↵↵<script type="text/javascript">↵ function getCookie(name) {↵ var cookieValue = null;↵ if (document.cookie && document.cookie !== '') {↵ var cookies = document.cookie.split(';');↵ for (var i = 0; i < cookies.length; i++) {↵ var cookie = jQuery.trim(cookies[i]);↵ // Does this cookie string begin with the name we want?↵ if (cookie.substring(0, name.length + 1) === (name + '=')) {↵ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));↵ break;↵ }↵ }↵ }↵ return cookieValue;↵ }↵↵ var csrftoken = getCookie('csrftoken');↵↵ function csrfSafeMethod(method) {↵ // these HTTP methods do not require CSRF protection↵ return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));↵ }↵ $.ajaxSetup({↵ beforeSend: function(xhr, settings) {↵ if (!csrfSafeMethod(settings.type) && !this.crossDomain) {↵ xhr.setRequestHeader("X-CSRFToken", csrftoken);↵ }↵ }↵ });↵</script>↵↵↵ ↵ ↵ </body>↵</html>↵↵" setRequestHeader : ƒ (e,t) state : ƒ () status : 403 statusCode : ƒ (e) statusText : "Forbidden" then : ƒ (t,r,i) __proto__ : Object

EDIT: I am sending CSRF separately like this in a js.html:

{# CSRF #} <script type="text/javascript"> function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); </script> <!-- place project specific Javascript in this file --> <script src="{% static 'js/project.js' %}"></script>

My original AJAX code is in project.js. The script file coming after.

最满意答案

如您所见,服务器返回状态码403 FORBIDDEN。 我想你应该在你的ajax请求中包含CSRF令牌。 你可以在这里阅读更多关于它的信息: https : //docs.djangoproject.com/en/1.11/ref/csrf/#ajax

As you can see, server returns status code 403 FORBIDDEN. I guess you should include CSRF token to your ajax request. You can read more about it here: https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax

更多推荐

本文发布于:2023-07-07 21:28:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1068447.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Django

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!