Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

javascript - How to pass csrf_token to the post params of editurl of jqgrid?

I'm using JqGrid with Django framework. That's JS:

      jQuery("#list").jqGrid({
        url:'{% url views.manage.devicesajax %}',
        datatype: 'json',
        mtype: 'GET',
        colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
        colModel :[ 
          {name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_firstseen', index:'d_firstseen', width: 80}, 
          {name:'d_lastseen', index:'d_lastseen', width: 80}],
        pager: jQuery('#pager'),
        rowNum:20,
        rowList:[20,50,100],
        sortname: 'did',
        sortorder: "desc",
        multiselect: true,
        viewrecords: true,
        imgpath: 'themes/basic/images',
        caption: 'Devices list',
        height: 330,
        width: 1000,
        onSelectRow: function(id) {
            var id = $("#list").getRowData(id).message_id;
            message_id = id;
        },
        editurl: "{% url views.manage.deviceseditajax %}"
    });

When I do edit row in JqGrid I get error from editurl:

Forbidden (403) CSRF verification failed. Request aborted.

It's because csrf_token doesn't pass to editurl with the other data. How to add csrf_token to the POST request to editurl ?

This code works perfectly ( complete piece of jqgrid init ):

     jQuery("#list").jqGrid({
        url:'{% url views.manage.devicesajax %}',
        datatype: 'json',
        mtype: 'GET',
        colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
        colModel :[ 
          {name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_firstseen', index:'d_firstseen', width: 80}, 
          {name:'d_lastseen', index:'d_lastseen', width: 80}],
        pager: jQuery('#pager'),
        rowNum:20,
        rowList:[20,50,100],
        sortname: 'did',
        sortorder: "desc",
        multiselect: true,
        viewrecords: true,
        imgpath: 'themes/basic/images',
        caption: 'Devices list',
        height: 330,
        width: 1000,
        editurl: "{% url views.manage.deviceseditajax %}",
    });

      jQuery("#list").navGrid('#pager',{edit:true,add:true,del:true,search:true},
        {
            closeAfterEdit:true,
            reloadAfterSubmit:true,
            closeOnEscape:true,
            editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        },
        {
            closeAfterAdd:true,
            reloadAfterSubmit:true,
            closeOnEscape:true,
            editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        }, 
        {
            closeOnEscape:true,
            delData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        }, 
        {
         caption: "Search",
         Find: "Find",
         Reset: "Reset",
         sopt  : ['eq', 'cn'],
         matchText: " match",
         rulesText: " rules",
         closeAfterSearch: true,
         afterShowSearch: function ()
         {
             $('#reset_filter1_block').show();
         }
       }
      );
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't use Django framework and not familiar with the csrf_token, but after searching in Google it seems that you need to set it in the HTTP header of the request: xhr.setRequestHeader('X-CSRF-Token', csrf_token);. To do this in case of jqGrid you can use loadBeforeSend event handler:

loadBeforeSend: function(jqXHR) {
    // you should modify the next line to get the CSRF tocken
    // in any way (for example $('meta[name=csrf]').attr('content')
    // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
    var csrf_token = '<%= token_value %>'; // any way to get
    jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}

See here for a very close problem.

UPDATED: To post additional data in case of form editing usage you can use editData: editData: { csrfmiddlewaretoken:'<%= token_value %>' }. For example:

jQuery("#list").jqGrid('navGrid','#pager',{},
    { // Edit option (parameters of editGridRow method)
        recreateForm:true,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterEdit:true,
        ajaxEditOptions: {
            beforeSend: function(jqXHR) {
                // you should modify the next line to get the CSRF tocken
                // in any way (for example $('meta[name=csrf]').attr('content')
                // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
                var csrf_token = '<%= token_value %>'; // any way to get
                jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
            }
        },
        editData: {
            csrfmiddlewaretoken: '<%= token_value %>'
        }
    },
    { // Add options (parameters of editGridRow method)
        recreateForm:true,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterAdd:true,
        ajaxEditOptions: {
            beforeSend: function(jqXHR) {
                // you should modify the next line to get the CSRF tocken
                // in any way (for example $('meta[name=csrf]').attr('content')
                // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
                var csrf_token = '<%= token_value %>'; // any way to get
                jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
            }
        },
        editData: {
            csrfmiddlewaretoken: '<%= token_value %>'
        }
    }
);

I placed here both ways: setting of 'X-CSRF-Token' HTTP header and posting of the csrfmiddlewaretoken parameter. You can remove one way after the corresponding experiments.

If you use some parameters for all grids on the page you can better change the defaults (see here for details)

jQuery.extend(jQuery.jgrid.edit, {
    recreateForm:true,
    reloadAfterSubmit:false,
    closeOnEscape:true,
    savekey: [true,13],
    closeAfterAdd:true,
    closeAfterEdit:true,
    ajaxEditOptions: {
        beforeSend: function(jqXHR) {
            // you should modify the next line to get the CSRF tocken
            // in any way (for example $('meta[name=csrf]').attr('content')
            // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
            var csrf_token = '<%= token_value %>'; // any way to get
            jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
        }
    },
    editData: {
        csrfmiddlewaretoken: '<%= token_value %>'
    }
});

The setting is common for both Add and Edit forms. So you can use navGrid in the simplified form.

jQuery("#list").jqGrid('navGrid','#pager');

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...