Context: a chrome browser extension uses JQuery to request a response from a remote django app. Django recognizes that the request is made via AJAX and responds with "Hello AJAX!". I'm basing my exercise off this great example. Because this request is being made from a chrome extension, the request is being made cross site, so I've used the @CSRF_exempt
decorator on my Django view.
上下文:chrome浏览器扩展使用JQuery请求来自远程django应用程序的响应。我的练习是基于这个很好的例子。因为这个请求来自chrome扩展,所以请求是跨站点的,所以我在Django视图上使用了@ csrf_豁免权decorator。
Problem: My Django view is not recognizing the request as an AJAX request, and instead of responding Hello AJAX!
it responds Hello not AJAX!
.
问题:我的Django视图没有将请求识别为AJAX请求,而没有响应Hello AJAX!它响应的是Hello而不是AJAX!
My Django view:
(The url /xhr_test
uses the following view)
我的Django视图:(url /xhr_test使用以下视图)
@csrf_exempt
def check_login_extension(request):
if request.is_ajax():
message = "Hello AJAX!"
else:
message = "Hello not AJAX"
return HttpResponse(message)
My JQuery request:
我的JQuery请求:
function xhrconnect() {
$.get("http://localhost:8000/xhr_test", function(data) {
document.getElementById('xhrmsg').innerHTML = (data);
});
}
2 个解决方案
#1
15
Going through the jQuery source, it looks like $.ajax()
(and therefore $.get()
, $.post()
, etc) will automatically set the crossDomain
option to true
if it sees that you're making a cross-domain request, which you are (relevant code here). And in the actual AJAX request, jQuery won't set the HTTP_X_REQUESTED_WITH
header that Django needs for is_ajax()
if crossDomain
is set (relevant code here).
通过jQuery源代码,它看起来像$.ajax()(因此,$.get()、$.post()等)将自动将crossDomain选项设置为true,如果它看到您正在进行跨域请求(相关代码在这里)。在实际的AJAX请求中,如果设置了crossDomain(这里的相关代码),jQuery不会设置Django需要的HTTP_X_REQUESTED_WITH报头。
I think the easiest way to fix this is to explicitly set crossDomain
to false
:
我认为解决这个问题最简单的方法是显式地将crossDomain设为false:
function xhrconnect() {
$.ajax({
url: "http://localhost:8000/xhr_test",
success: function(data) {
document.getElementById('xhrmsg').innerHTML = (data);
},
crossDomain: false
});
}
If that doesn't work, you could try using an AJAX prefilter function to manually set the HTTP_X_REQUESTED_WITH
header on the request.
如果这不起作用,您可以尝试使用AJAX prefilter函数在请求上手动设置http_x_requested_withheader。
#2
0
You may also want to take a look at this page. Because Django provides some protection against cross-site request forgeries (CSRF), it requires some special AJAX setup. I've included the AJAX setup below:
你也可以看看这一页。由于Django为跨站点请求伪造提供了一些保护,因此需要一些特殊的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'));
}
});
#1
15
Going through the jQuery source, it looks like $.ajax()
(and therefore $.get()
, $.post()
, etc) will automatically set the crossDomain
option to true
if it sees that you're making a cross-domain request, which you are (relevant code here). And in the actual AJAX request, jQuery won't set the HTTP_X_REQUESTED_WITH
header that Django needs for is_ajax()
if crossDomain
is set (relevant code here).
通过jQuery源代码,它看起来像$.ajax()(因此,$.get()、$.post()等)将自动将crossDomain选项设置为true,如果它看到您正在进行跨域请求(相关代码在这里)。在实际的AJAX请求中,如果设置了crossDomain(这里的相关代码),jQuery不会设置Django需要的HTTP_X_REQUESTED_WITH报头。
I think the easiest way to fix this is to explicitly set crossDomain
to false
:
我认为解决这个问题最简单的方法是显式地将crossDomain设为false:
function xhrconnect() {
$.ajax({
url: "http://localhost:8000/xhr_test",
success: function(data) {
document.getElementById('xhrmsg').innerHTML = (data);
},
crossDomain: false
});
}
If that doesn't work, you could try using an AJAX prefilter function to manually set the HTTP_X_REQUESTED_WITH
header on the request.
如果这不起作用,您可以尝试使用AJAX prefilter函数在请求上手动设置http_x_requested_withheader。
#2
0
You may also want to take a look at this page. Because Django provides some protection against cross-site request forgeries (CSRF), it requires some special AJAX setup. I've included the AJAX setup below:
你也可以看看这一页。由于Django为跨站点请求伪造提供了一些保护,因此需要一些特殊的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'));
}
});