【发布时间】:2014-12-20 22:33:33
【问题描述】:
我正在尝试捕获 HTML 表单的提交(由 Django 呈现)并使用 ajax 处理它,而不是重定向到新页面,但是似乎从未调用过 javascript 函数。这是我渲染的 html:
<form action="" id="id_create_review" method="post">
<div id="div_id_session" class="form-group">
<label for="id_session" class="control-label ">
Session
</label>
<div class="controls ">
<select class="select form-control" id="id_session" name="session">
<option value="" selected="selected">---------</option>
<option value="1">Rocky Balboa Boxing Club</option>
<option value="2">All about the Box...ing</option>
</select>
</div>
</div>
<div id="div_id_rating" class="form-group">
<label for="id_rating" class="control-label requiredField">
Rating<span class="asteriskField">*</span>
</label>
<div class="controls ">
<select class="select form-control" id="id_rating" name="rating">
<option value="0.0">0.0</option>
<option value="0.5">0.5</option>
<option value="1.0">1.0</option>
<option value="1.5">1.5</option>
<option value="2.0">2.0</option>
<option value="2.5" selected="selected">2.5</option>
<option value="3.0">3.0</option>
<option value="3.5">3.5</option>
<option value="4.0">4.0</option>
<option value="4.5">4.5</option>
<option value="5.0">5.0</option>
</select>
</div>
</div>
<div id="div_id_comments" class="form-group">
<label for="id_comments" class="control-label requiredField">
Comments<span class="asteriskField">*</span>
</label>
<div class="controls ">
<textarea class="textarea form-control" cols="40" id="id_comments" name="comments" rows="10"></textarea>
</div>
</div>
<div class="form-group">
<div id="div_id_would_recommend" class="checkbox">
<label for="id_would_recommend" class="">
<input checked="checked" class="checkboxinput checkbox" id="id_would_recommend" name="would_recommend" type="checkbox">
Would recommend
</label>
</div>
</div>
<div class="form-group">
<div id="div_id_anonymous" class="checkbox">
<label for="id_anonymous" class="">
<input checked="checked" class="checkboxinput checkbox" id="id_anonymous" name="anonymous" type="checkbox">
Anonymous
</label>
</div>
</div>
<div class="form-actions">
<input type="submit" name="submit" value="Send Review" class="btn btn-primary" id="submit-id-submit">
</div>
</form>
这是我在底部的 javascript:
<script type="text/javascript">
$(document).ready(function() {
$('#id_create_review').submit(function() { // catch the form's submit event
console.log('Yeah, no?');
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response) { // on success..
$('#success_div').html(response); // update the DIV
},
error: function(e, x, r) { // on error..
$('#error_div').html(e); // update the DIV
}
});
return false;
});
});
</script>
编辑
因此,由于 CSRF 保护失败,我收到了 403 错误。如果请求是使用 ajax 发出的,我有一些 javascript 应该可以防止这个 403 错误,我也没有看到“是的,不是吗?”登录到控制台,所以我认为必须通过标准 Http 提交表单。
也许我的问题是表单正在由 javascript 处理,但是 ajax 请求仍然导致 403 错误?但是为什么在我的 JS 中看不到控制台日志呢?
如果问题是我的 ajax 请求导致了 403 错误,为什么我的保护代码无法发送 csrf 令牌?我不能说我 100% 理解所有这些......我主要是从使用 django 处理 ajax 请求的在线教程中获取的。代码如下:
<script>
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');
/*
The functions below will create a header with csrftoken
*/
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
</script>
【问题讨论】:
-
你试过调试你的脚本吗?代码看起来很合理...很可能与您显示的代码无关(例如重复的 ID 或脚本中的语法错误)...
-
我创建了这个 FIDDLE DEMO 。代码似乎运行良好,检查控制台。
-
检查你的 jQuery 库脚本标签
-
如果你没有得到初始的 console.log("yeah, no"),那么 jQuery 就没有被加载。您可以在 $(document).ready() 之后立即执行 console.log() 吗?我还会检查您的 Web 开发人员工具,以查看您的所有链接脚本或外部文件是否正在加载。一些防火墙可以阻止某些连接
-
是的,正在加载 jQuery。我在页面上还有其他 jQuery 效果也可以正常工作。
标签: javascript jquery html ajax django