Django说在jQuery AJAX请求中is_ajax是假的

时间:2011-10-13 14:42:15

标签: jquery ajax django google-chrome-extension

上下文: Chrome浏览器扩展程序使用JQuery从远程django应用程序请求响应。 Django认识到请求是通过AJAX进行的,并以“Hello AJAX!”响应。我的工作基于this great example。因为此请求是通过chrome扩展进行的,所以请求是跨站点进行的,所以我在Django视图中使用了@CSRF_exempt装饰器。

问题:我的Django视图未将请求识别为AJAX请求,而是响应Hello AJAX!而不是响应Hello not AJAX!

我的Django观点:
(网址/xhr_test使用以下视图)

@csrf_exempt
def check_login_extension(request):
    if request.is_ajax():
        message = "Hello AJAX!"
    else:
        message = "Hello not AJAX"
    return HttpResponse(message)

我的JQuery请求:

function xhrconnect() {
    $.get("http://localhost:8000/xhr_test", function(data) {
      document.getElementById('xhrmsg').innerHTML = (data);
    });
}

2 个答案:

答案 0 :(得分:15)

通过jQuery源代码,看起来$.ajax()(因此$.get()$.post()等)会自动将crossDomain选项设置为true如果它发现您正在制作跨域请求,那么您就是{relevant code here)。在实际的AJAX请求中,如果设置了HTTP_X_REQUESTED_WITHrelevant code here),jQuery将不会设置Django is_ajax()所需的crossDomain标头。

我认为解决此问题的最简单方法是明确将crossDomain设置为false

function xhrconnect() {
    $.ajax({
        url: "http://localhost:8000/xhr_test", 
        success: function(data) {
            document.getElementById('xhrmsg').innerHTML = (data);
        },
        crossDomain: false
    });
}

如果这不起作用,您可以尝试使用AJAX prefilter function在请求上手动设置HTTP_X_REQUESTED_WITH标头。

答案 1 :(得分:0)

您可能还想查看this page。因为Django提供了一些针对跨站点请求伪造(CSRF)的保护,所以它需要一些特殊的AJAX设置。我在下面列出了AJAX设置:

$(document).ajaxSend(function(event, xhr, settings) {
    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;
    }
    function sameOrigin(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));
    }
    function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    }
});