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:2开发者_如何学编程0,
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();
}
}
);
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');
Check your cookies. Django's CSRF also save a cookie csrftoken
which does have the same value as the csrf_token which you would use in a form. You can use any Javascript cookie library to get the cookie and pass it to the POST request as csrfmiddlewaretoken
.
According to the jqGrid documentation, you can pass a postData options. If you're using jQuery Cookie plugin, you can add something like :
postData: {
csrfmiddlewaretoken: $.cookie(CSRF_COOKIE_NAME)
},
to your list of options to jqGrid.
The CSRF_COOKIE_NAME is set in your django application settings.py and is 'csrftoken' by default.
I found simple solution using latest JqGrid and Inline Edit submit csrf_token to request POST django without @csrf_exempt
onSelectRow: function(id){
if(id && id!==lastSel){
$(selector).restoreRow(lastSel);
lastSel=id;
}
var editparameters = {
extraparam: {csrfmiddlewaretoken: $('.token-data').data('token')},
keys: true,
};
$(selector).jqGrid('editRow', id, editparameters);
}
For example, please see on my blog post: http://yodi.polatic.me/jqgrid-inline-editing-integration-with-django-send-csrf-token/
精彩评论