jQuery ajax beforeSend 隐藏了`$.ajaxSetup` 一个,如何级联呢?
jQuery ajax beforeSend shadows the `$.ajaxSetup` one, How to cascade it?
我正在使用 django-rest-framework。
而且我必须在每次 jquery ajax 发送之前添加 X-CSRFToken
header。
参考:https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax
jQuery.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
}
});
所以,一切都很好,直到我使用给定的 beforeSend 设置进行 ajax 调用:
jQuery.ajax({
url: '...',
data: { ... },
beforeSend: function(xhr, settings) {
// This function do shadows the ajaxSetup one.
}
});
那么,有什么有效的方法可以在 jQuery.ajaxSetup
调用中级联 beforeSend 处理器吗?
如果在 $.ajaxSetup
中定义一个新的 beforeSend
注入,我可以级联之前 $.ajaxSetup
中定义的其他注入:
(function() {
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
var originBeforeSend = jQuery.ajaxSettings.beforeSend;
jQuery.ajaxSetup({
beforeSend: function(xhr, settings) {
// Call the previous beforeSend processor first.
if(originBeforeSend && originBeforeSend(xhr, settings) === false) {
return false;
}
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
}
});
})();
但是无论如何,如果我在 $.ajax()
调用中指定了另一个 beforeSend
,这种方式就没有运气了。还是有阴影的。
事实上,在jQuery Event的jQuery文档中,设置beforeSend
来自$.ajax
调用或$.ajaxSetup
被称为Local Event,但在当前情况下,使用称为 Global Event 的 $(document).ajaxSend()
更合适。
最终解决方案
如果您想在 ajax 发送上添加多个全局事件处理器,请不要在 $.ajaxSetup
上设置。
改为使用 ajaxSend
事件!
http://api.jquery.com/ajaxSend/
因此代码可能如下所示:
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$(document).ajaxSend(function(event, xhr, settings) {
if (!csrfSafeMethod(settings.type) && !settings.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
});
我正在使用 django-rest-framework。
而且我必须在每次 jquery ajax 发送之前添加 X-CSRFToken
header。
参考:https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax
jQuery.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
}
});
所以,一切都很好,直到我使用给定的 beforeSend 设置进行 ajax 调用:
jQuery.ajax({
url: '...',
data: { ... },
beforeSend: function(xhr, settings) {
// This function do shadows the ajaxSetup one.
}
});
那么,有什么有效的方法可以在 jQuery.ajaxSetup
调用中级联 beforeSend 处理器吗?
如果在 $.ajaxSetup
中定义一个新的 beforeSend
注入,我可以级联之前 $.ajaxSetup
中定义的其他注入:
(function() {
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
var originBeforeSend = jQuery.ajaxSettings.beforeSend;
jQuery.ajaxSetup({
beforeSend: function(xhr, settings) {
// Call the previous beforeSend processor first.
if(originBeforeSend && originBeforeSend(xhr, settings) === false) {
return false;
}
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
}
});
})();
但是无论如何,如果我在 $.ajax()
调用中指定了另一个 beforeSend
,这种方式就没有运气了。还是有阴影的。
事实上,在jQuery Event的jQuery文档中,设置beforeSend
来自$.ajax
调用或$.ajaxSetup
被称为Local Event,但在当前情况下,使用称为 Global Event 的 $(document).ajaxSend()
更合适。
最终解决方案
如果您想在 ajax 发送上添加多个全局事件处理器,请不要在 $.ajaxSetup
上设置。
改为使用 ajaxSend
事件!
http://api.jquery.com/ajaxSend/
因此代码可能如下所示:
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$(document).ajaxSend(function(event, xhr, settings) {
if (!csrfSafeMethod(settings.type) && !settings.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
}
});