Django中ajax發送post請求,報403錯誤CSRF驗證失敗解決辦法

今天學習Django框架,用ajax向後臺發送post請求,直接報了403錯誤,說CSRF驗證失敗;先前用模板的話都是在裏面加一個 {% csrf_token %} 就直接搞定了CSRF的問題了;很顯然,用ajax發送post請求這樣就白搭了;html

 文末已經更新更簡單的方法,上面的略顯麻煩

上網上查了一下,看了幾個別人的博客,才知道官網也早有說明解決辦法,大體流程就是:ajax

 

就是新建一個JavaScript文件,而後把網上給的代碼粘貼進去,而後在你使用ajax的頁面把它引入一下;固然,若是你在網上找到的解決代碼包含JQuery的話,那就須要在引入的JQuery以後引入了(畢竟解決代碼不惟一,網上一找一堆,基本都是對的,原生JS和帶JQuery的都有);json

文末會附上我使用的JS相關代碼,也能夠去網上找!後端

 

若是上述沒有解決你的問題,那就說明你和我踩了一樣的一個小坑........api

 

用了上面查到的方法,直接就解決了個人問題,可是隨着我對代碼修修改改、清除了相關頁面的cookie,吃個飯再運行,居然又報403的CSRF錯誤了;百思不得其解的我又去Django官網看了一下相關部分的文檔,一堆英文看看大概找到了問題;瀏覽器

我發現我把html頁面裏面原先加的 {% csrf_token %} 這個東西給刪掉了,加上谷歌的相關頁面cookie被我一清除,csrftoken就被咔嚓了,再刷新頁面,去html頁面裏也找不到 {% csrf_token %} ,沒有了csrftoken那個cookie值,即便有相關的JS代碼也毛用沒有了;cookie

 

打個比方:框架

  • 你吃飯須要工具,也就是筷子,可是飯都沒有,你拿個筷子吃什麼呀!!!
  • 這裏的筷子就是解決問題的JS代碼,而飯就是這個 {% csrf_token %} ,更確切說因該是瀏覽器中的叫 csrftoken 的 cookie;
  • 二者都有了,才能完全解決吃飯的問題;

 

總結下來:工具

  • 使用ajax發送post請求時,html頁面裏必定要有 {% csrf_token %},在body裏應該就沒什麼大問題;
  • 而後引入相關的JS解決代碼;
  • 補充一下,和表單沒什麼太大關係,由於個人html頁面裏就沒有表單,直接經過點擊按鈕發送的ajax請求;

  

 

 

須要引入的相關JS代碼post

 

 

 1 $(document).ajaxSend(function(event, xhr, settings) {
 2     function getCookie(name) {
 3         var cookieValue = null;
 4         if (document.cookie && document.cookie != '') {
 5             var cookies = document.cookie.split(';');
 6             for (var i = 0; i < cookies.length; i++) {
 7                 var cookie = jQuery.trim(cookies[i]);
 8                 // Does this cookie string begin with the name we want?
 9                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
10                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
11                     break;
12                 }
13             }
14         }
15         return cookieValue;
16     }
17     function sameOrigin(url) {
18         // url could be relative or scheme relative or absolute
19         var host = document.location.host; // host + port
20         var protocol = document.location.protocol;
21         var sr_origin = '//' + host;
22         var origin = protocol + sr_origin;
23         // Allow absolute or scheme relative URLs to same origin
24         return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
25             (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
26             // or any other URL that isn't scheme relative or absolute i.e relative.
27             !(/^(\/\/|http:|https:).*/.test(url));
28     }
29     function safeMethod(method) {
30         return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
31     }
32  
33     if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
34         xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
35     }
36 });

 簡單方法

  • 首先在你須要發起ajax post請求的頁面的裏面隨便一個地方加上 {% crsr_token %}
  • 而後瀏覽器裏查看源碼,會有這麼一個隱藏標籤:<input type="hidden" name="csrfmiddlewaretoken" value="jlYb5LCP21TxGapw7OuO0xbHmRnyFzlgDapiDl1M1Vp6dOjPM4BlHOgOVeuPYQ27">
  • 在發起ajax post 請求時,組織json參數時,如下面這種方式使其成爲參數,前兩個參數是我自定義的請自行忽略,其中鍵值對中的鍵名爲input標籤的name名,值就爲其value值
    csrf = $('input[name="csrfmiddlewaretoken"]').val();
    params = {'sku_id': sku_id, 'count': count, 'csrfmiddlewaretoken': csrf};
  • 這樣就能夠把csrf中的參數傳遞給後端,就不會有403錯誤了,相比前面用了好大一段JS代碼要簡潔的多
相關文章
相關標籤/搜索