M

AJAX and JSON-RPC with Django

JSON-RPC and Django

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over http, or in many various message passing environments. It uses JSON (RFC 4627) as data format.

URL dispatcher

url(r'^ajaxjsonrpc/$', views.jsonrpc, name='jsonrpc')

View/Controller

@methods.add
def ping(request):
    data = request
    # Work with json data received
    return 'pong'


@csrf_protect
def jsonrpc(request):
    print "jsonrpc"
    response = methods.dispatch(request.body.decode())
    return JsonResponse(response, status=response.http_status)

JavaScript

Django use Cross Site Request Forgery protection, to avoid the error CSRF verification failed. Request aborted. it is needed to pass django csrf token with javascript we can use the next code:

<script>

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

</script>

Using json rpc we can send the data via HTTP POST to our url previously created in order to be able to manage by our custom view/controller ping.

<script>

data = { "item": "one", "item2": "two"  }

$.jrpc("http://127.0.0.1:8000/ajaxjsonrpc/",
      "ping",
      [data],
      function(data) {
          alert(data);
          console.log(data);
      }
);

</script>

AJAX and Django

AJAX (Asynchronous JavaScript And XML) is not a programming language. AJAX just uses a combination of, a browser built-in XMLHttpRequest object (to request data from a web server) and, JavaScript and HTML DOM (to display or use the data). AJAX allows web pages to be updated asynchronously by exchanging data with a web server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.

URL dispatcher

url(r'^ajax/AJAXviewsExample/$', views.AJAXviewsExample, name='AJAXviewsExample')
url(r'^ajax/AJAXviewsGET/$', views.AJAXviewsGET, name='AJAXviewsGET')
url(r'^ajax/AJAXviewsPOST/$', views.AJAXviewsPOST, name='AJAXviewsPOST')

View/Controller

@csrf_protect
def AJAXviewsExample(request):
  if request.method == 'GET':
       print "DATA" + str(request)
  elif request.method == 'POST':
       print "DATA" + str(request.POST.get('data'))

@csrf_protect
def AJAXviewsGET(request):
    if request.is_ajax():
        items = ['one 1', 'two 2']
        data = json.dumps(items)
        return HttpResponse(data, content_type='application/json')
    else:
        raise Http404

@csrf_protect
def AJAXviewsPOST(request):
    print "add_todo 1"
    if request.is_ajax() and request.POST:
        print "add_todo 2"
        data = {'message': "%s added" % request.POST.get('item')}
        return HttpResponse(json.dumps(data), content_type='application/json')
    else:
        raise Http404

JavaScript

Django use Cross Site Request Forgery protection, to avoid the error ‘CSRF verification failed. Request aborted.’ it is needed to pass django csrf token with javascript we can use the next code:

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

</script>

Using AJAX we can send the data via HTTP GET or POST to our url previously created in order to be manage by our custom views/controllers AJAXviewsGET and AJAXviewsPOST.

<script>

// GET 

$.ajax({
    type: "GET",
    url: "http://127.0.0.1:8000/ajax/AJAXviewsGET/",
    success: function(data) {
        for(i = 0; i < data.length; i++){
          $('ul').append('<li>'+data[i]+'</li>');
      }
    }
});


// POST

$.ajax({
    type: "POST",
    url: "http://127.0.0.1:8000/ajax/AJAXviewsPOST/",
    dataType: "json",
    data: { "item": "one" },
    success: function(data) {
        alert(data.message);
        console.log(data);
    }
});

</script>