在开发过程中,我有一个可行的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]
'public'指的是:
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  CONTACT  TERMS  PRIVACY  BLOG</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中。之后的脚本文件。
答案 0 :(得分:1)
如您所见,服务器返回状态码403 FORBIDDEN。我想你应该在你的ajax请求中包含CSRF令牌。您可以在此处详细了解:https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax