Most JavaScript frameworks set the X-Requested-With HTTP Header to XMLHttpRequest when sending non-cross-domain XHR requests. Many web frameworks like Django or Flask use this to detect AJAX requests.
Because of issues with X-Requested-With and cross-domain XHR requests, d3.js does not set that header by default. Therefore Django's request.is_ajax() and Flask's request.is_xhr() break.
In order to make d3 work with those AJAX detection functions, you need to manually add the header to the request. Instead of
d3.json("/path", function(error, data) {
// Process data
});
you would write
d3.json("/path").header("X-Requested-With", "XMLHttpRequest").get(function(error, data) {
// Process data
});
Warning: Never use the X-Requested-With header as a security feature. It provides no security whatsoever and can always be faked.