【问题标题】:Django: Ajax call not working in chrome. Working in firefoxDjango:Ajax 调用在 chrome 中不起作用。在火狐中工作
【发布时间】:2014-09-26 06:00:51
【问题描述】:

更新:我发现了问题(我认为)。我认为这本身不是浏览器问题,而是速度问题。当我通过以下方式打印出 csrftoken 时:

var csrftoken = getCookie('csrftoken');
console.log(csrftoken)

在我的本地机器上,我在控制台中获得了令牌。不过,在我的实时版本中,令牌为空。我将为此提出一个新问题,因为实际问题已经发生了很大变化。

编辑:根据朋友的建议,我将输入和按钮放入带有 {$ csrf_token %} 标签的表单中。我还在 ajax 帖子中传递了“csrfmiddlewaretoken”。这也不再适用于 Firefox,但我认为该方法正在改进,因为这种方法似乎对他有用:/。我已经更新了问题的代码 sn-ps 以符合当前的实现

' '下面的原始问题 '

总的来说,我是 Django 和 Web 开发的初学者,我正在尝试设置一个简单的应用程序。本质上,我想要做的是有一个输入框和一个按钮。单击按钮时,输入框的内容会使用 ajax 回传到服务器并被视图捕获。然后,我将在视图中处理输入框的内容并发送回一个简单的 json 对象。代码:

HTML

<div class="input-text">
                Enter the Map ID provided to you by ... below
            </div>

            <form onsubmit="return false;">
                {% csrf_token %}
                <input type="text" id="map-id-input">
                <button id="map-id-btn" class='btn btn-default custom-btn' onclick="checkMapID()">
                    Go 
                </button>
             </form>

JavaScript

function checkMapID() {
var mapId = $("#map-id-input").val();
$.ajax({
    url: "check_map_id/", 
    type: "POST",
    dataType: "json", 
    data: {
        csrfmiddlewaretoken: '{{ csrf_token }}',
        map_id: mapId,
    },
    success: function(status_dict) {
        if (status_dict.status === 1) {
            $("#status").html("Valid map ID <br> Loading Data...")
            window.location = status_dict.url;
        }
        else {
            $("#status").html("Invalid map ID. Please try again, or contact MRCagney")
        }
    },
    error: function(result) {
        console.log(result)
    }
});

}

Django 网址

url(r'^check_map_id/$', views.check_map_id),

Django 视图

@ensure_csrf_cookie
def check_map_id(request):
map_id = request.POST['map_id']

if map_id not in GEOJSON_LOOKUP.keys():
    status = json.dumps({
        'status': 0,
        'url': '',
    })  
    return HttpResponse(status, content_type="application/json")
else:
    status = json.dumps({
        'status': 1,
        'url': reverse('map', args=(map_id,)),
    })
    return HttpResponse(status, content_type="application/json")

这就是我想要做的所有事情。我应该说,我已经添加了所需的代码(在 django 文档中定义)来设置 ajax 标头:

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({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

这在 Firefox 中运行良好,但在 Chrome 中,每当我单击按钮时都会收到 403 错误。错误是:

Object {readyState: 4, getResponseHeader: function, getAllResponseHeaders: function, 

setRequestHeader: function, overrideMimeType: function…}
abort: function (a){var b=a||u;return c&&c.abort(b),x(0,b),this}
always: function (){return e.done(arguments).fail(arguments),this}
complete: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
done: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
error: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
fail: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
getAllResponseHeaders: function (){return 2===t?e:null}
getResponseHeader: function (a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b}
overrideMimeType: function (a){return t||(k.mimeType=a),this}
pipe: function (){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()}
progress: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
promise: function (a){return null!=a?n.extend(a,d):d}
readyState: 4
responseText: "↵<!DOCTYPE html>↵<html lang="en">↵<head>↵  <meta http-equiv="content-type" content="text/html; charset=utf-8">↵  <meta name="robots" content="NONE,NOARCHIVE">↵  <title>403 Forbidden</title>↵  <style type="text/css">↵    html * { padding:0; margin:0; }↵    body * { padding:10px 20px; }↵    body * * { padding:0; }↵    body { font:small sans-serif; background:#eee; }↵    body>div { border-bottom:1px solid #ddd; }↵    h1 { font-weight:normal; margin-bottom:.4em; }↵    h1 span { font-size:60%; color:#666; font-weight:normal; }↵    #info { background:#f6f6f6; }↵    #info ul { margin: 0.5em 4em; }↵    #info p, #summary p { padding-top:10px; }↵    #summary { background: #ffc; }↵    #explanation { background:#eee; border-bottom: 0px none; }↵  </style>↵</head>↵<body>↵<div id="summary">↵  <h1>Forbidden <span>(403)</span></h1>↵  <p>CSRF verification failed. Request aborted.</p>↵↵↵  <p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>↵  <p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for &#39;same-origin&#39; requests.</p>↵↵</div>↵↵<div id="explanation">↵  <p><small>More information is available with DEBUG=True.</small></p>↵</div>↵↵</body>↵</html>↵"
setRequestHeader: function (a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this}
state: function (){return c}
status: 403
statusCode: function (a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this}
statusText: "FORBIDDEN"
success: function (){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this}
then: function (){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()}
__proto__: Object

我在这里缺少什么简单的东西吗?

非常感谢您花时间阅读所有内容!

【问题讨论】:

  • 如果它在 firefox 上运行而不在 chrome 上运行,则清理两者的缓存并再次检查:)
  • 不幸的是,这在这种情况下不起作用:/

标签: html ajax django post django-views


【解决方案1】:

我遇到了同样的问题。设置标题适用于 Firefox,但不适用于 chrome。 我做了什么:

var fd = {};
fd['csrfmiddlewaretoken'] = $.csrf_token;

fd 是我通过 AJAX 发送的表单数据。 $.csrf_token 是全局对象,我定义它打印令牌到模板。

之后(标题+表单数据)一切正常。 注意:在几种情况下,我有另一种方法,我正在模拟我发送的数据,就像表单一样。

var fd = new FormData();
fd.append('csrfmiddlewaretoken', $.csrf_token);

你也可以试试这个。 (在这种情况下,您应该将 processData: false, contentType: false, 添加到 AJAX 请求设置中。)

还有一件事:我认为你应该使用 jquery.cookie 插件而不是定义自己的函数。

【讨论】:

  • 是 fd['csrfmiddlewaretoken'] = $.csrf_token;同:csrfmiddlewaretoken: csrftoken, where var csrftoken = getCookie('csrftoken');?
  • 在标头设置中,您应该从 cookie 中获取令牌。对于表单数据,我得到它,使用模板将令牌写入 js 变量。
【解决方案2】:

虽然问题没有解决,但我想我已经找到了原因。在我的本地机器上,打印出 csrftoken 变量会在控制台中生成一个令牌。但是,在我的实时版本中,无论使用哪种浏览器,都不会打印出令牌,而是将其设置为 null。代码位于模板顶部的脚本中:

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');
console.log(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);
        }
    }
});

我将针对为什么会发生这种情况提出一个新问题(因为我不知道!)

【讨论】:

    猜你喜欢
    • 2016-02-23
    • 2011-12-24
    • 2016-01-05
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2017-10-16
    相关资源
    最近更新 更多