#18826: A bit changed JavaScript for CSRF with async JS
-------------------------------------+-------------------------------------
     Reporter:  panco                |                    Owner:  nobody
         Type:                       |                   Status:  closed
  Cleanup/optimization               |                  Version:  1.4
    Component:  Documentation        |               Resolution:
     Severity:  Normal               |  worksforme
     Keywords:  ajax, csrf           |             Triage Stage:  Design
    Has patch:  0                    |  decision needed
  Needs tests:  0                    |      Needs documentation:  0
Easy pickings:  0                    |  Patch needs improvement:  0
                                     |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by lrekucki):

 * cc: lrekucki@… (added)


Old description:

> Recently I've found use for the code found at
> https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
> and as I can't sleep well if my JS doesn't pass some of the basic JSlint
> standards I've changed the snippet a bit:
> {{{
> jQuery(document).ajaxSend(function (event, xhr, settings) {
>         function getCookie(name) {
>                 var cookieValue = null, cookies = [], i = 0, j = 0,
> cookie = {};
>                 if (document.cookie && document.cookie !== '') {
>                         cookies = document.cookie.split(';');
>                         for (j = cookies.length; i < j; i += 1) {
>                                 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
>                         protocol = document.location.protocol,
>                         sr_origin = '//' + host,
>                         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'));
>         }
> });
> }}}
>
> * "===" instead of "=="
> * all vars at the beginning of the function (and all the changes that
> brings forth)
>
> I realize these changes are very small, but I think since this is a
> simple copy/paste snippet it should be of the highest quality possible
> (there's room for improvement still).
> I'm using it and it performs as intended.

New description:

 Recently I've found use for the code found at
 https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
 and as I can't sleep well if my JS doesn't pass some of the basic JSlint
 standards I've changed the snippet a bit:
 {{{
 #!javascript +line-numbers
 jQuery(document).ajaxSend(function (event, xhr, settings) {
         function getCookie(name) {
                 var cookieValue = null, cookies = [], i = 0, j = 0, cookie
 = {};
                 if (document.cookie && document.cookie !== '') {
                         cookies = document.cookie.split(';');
                         for (j = cookies.length; i < j; i += 1) {
                                 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
                         protocol = document.location.protocol,
                         sr_origin = '//' + host,
                         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'));
         }
 });
 }}}

 * "===" instead of "=="
 * all vars at the beginning of the function (and all the changes that
 brings forth)

 I realize these changes are very small, but I think since this is a simple
 copy/paste snippet it should be of the highest quality possible (there's
 room for improvement still).
 I'm using it and it performs as intended.

--

Comment:

 I mainly meant things like:

 * 8 spaces of indentation;
 * very long line ending with a comment;
 * initializing {{{cookie}}} to an object while it's later assigned a
 string;
 * not initializing value of {{{i}}} in the loop while initializing a
 {{{j}}} with list length for a premature optimization.

 Changing to {{{===}}} is ok, while hoisting all the variables to the top,
 IMHO, actually makes the code less readable (but it's probably a matter of
 taste).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/18826#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to