Django中ajax發(fā)送post請(qǐng)求 報(bào)403錯(cuò)誤CSRF驗(yàn)證失敗解決方案
前言
今天學(xué)習(xí)Django框架,用ajax向后臺(tái)發(fā)送post請(qǐng)求,直接報(bào)了403錯(cuò)誤,說CSRF驗(yàn)證失敗;先前用模板的話都是在里面加一個(gè) {% csrf_token %} 就直接搞定了CSRF的問題了;很顯然,用ajax發(fā)送post請(qǐng)求這樣就白搭了;
文末已經(jīng)更新更簡單的方法,上面的略顯麻煩
上網(wǎng)上查了一下,看了幾個(gè)別人的博客,才知道官網(wǎng)也早有說明解決辦法,大致流程就是:
就是新建一個(gè)JavaScript文件,然后把網(wǎng)上給的代碼粘貼進(jìn)去,然后在你使用ajax的頁面把它引入一下;當(dāng)然,如果你在網(wǎng)上找到的解決代碼包含JQuery的話,那就需要在引入的JQuery之后引入了(畢竟解決代碼不唯一,網(wǎng)上一找一堆,基本都是對(duì)的,原生JS和帶JQuery的都有);
文末會(huì)附上我使用的JS相關(guān)代碼,也可以去網(wǎng)上找!
如果上述沒有解決你的問題,那就說明你和我踩了同樣的一個(gè)小坑........
用了上面查到的方法,直接就解決了我的問題,但是隨著我對(duì)代碼修修改改、清除了相關(guān)頁面的cookie,吃個(gè)飯?jiān)龠\(yùn)行,竟然又報(bào)403的CSRF錯(cuò)誤了;百思不得其解的我又去Django官網(wǎng)看了一下相關(guān)部分的文檔,一堆英文看看大概找到了問題;
我發(fā)現(xiàn)我把html頁面里面原先加的 {% csrf_token %} 這個(gè)東西給刪掉了,加上谷歌的相關(guān)頁面cookie被我一清除,csrftoken就被咔嚓了,再刷新頁面,去html頁面里也找不到 {% csrf_token %} ,沒有了csrftoken那個(gè)cookie值,即使有相關(guān)的JS代碼也毛用沒有了;
打個(gè)比方:
- 你吃飯需要工具,也就是筷子,但是飯都沒有,你拿個(gè)筷子吃什么呀?。?!
- 這里的筷子就是解決問題的JS代碼,而飯就是這個(gè) {% csrf_token %} ,更確切說因該是瀏覽器中的叫 csrftoken 的 cookie;
- 兩者都有了,才能徹底解決吃飯的問題;
總結(jié)下來:
- 使用ajax發(fā)送post請(qǐng)求時(shí),html頁面里一定要有 {% csrf_token %},在body里應(yīng)該就沒什么大問題;
- 然后引入相關(guān)的JS解決代碼;
- 補(bǔ)充一下,和表單沒什么太大關(guān)系,因?yàn)槲业膆tml頁面里就沒有表單,直接通過點(diǎn)擊按鈕發(fā)送的ajax請(qǐng)求;
需要引入的相關(guān)JS代碼
$(document).ajaxSend(function(event, xhr, settings) { 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; } function sameOrigin(url) { // url could be relative or scheme relative or absolute var host = document.location.host; // host + port var protocol = document.location.protocol; var sr_origin = '//' + host; var 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')); } });
簡單方法
- 首先在你需要發(fā)起ajax post請(qǐng)求的頁面的里面隨便一個(gè)地方加上 {% crsr_token %}
- 然后瀏覽器里查看源碼,會(huì)有這么一個(gè)隱藏標(biāo)簽:<input type="hidden" name="csrfmiddlewaretoken" value="jlYb5LCP21TxGapw7OuO0xbHmRnyFzlgDapiDl1M1Vp6dOjPM4BlHOgOVeuPYQ27">
- 在發(fā)起ajax post 請(qǐng)求時(shí),組織json參數(shù)時(shí),以下面這種方式使其成為參數(shù),前兩個(gè)參數(shù)是我自定義的請(qǐng)自行忽略,其中鍵值對(duì)中的鍵名為input標(biāo)簽的name名,值就為其value值
- csrf = $('input[name="csrfmiddlewaretoken"]').val();
- params = {'sku_id': sku_id, 'count': count, 'csrfmiddlewaretoken': csrf};
- 這樣就可以把csrf中的參數(shù)傳遞給后端,就不會(huì)有403錯(cuò)誤了,相比前面用了好大一段JS代碼要簡潔的多
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python中字典(Dictionary)用法實(shí)例詳解
這篇文章主要介紹了python中字典(Dictionary)用法,以實(shí)例形式較為詳細(xì)的分析了Python字典建立、添加、刪除等常見操作技巧,需要的朋友可以參考下2015-05-05Flask框架實(shí)現(xiàn)debug模式下計(jì)算pin碼
pin碼也就是flask在開啟debug模式下,進(jìn)行代碼調(diào)試模式的進(jìn)入密碼。本文為大家整理了Flask框架在debug模式下計(jì)算pin碼的方法,需要的可以參考一下2023-02-02老生常談python函數(shù)參數(shù)的區(qū)別(必看篇)
下面小編就為大家?guī)硪黄仙U刾ython函數(shù)參數(shù)的區(qū)別(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05Python使用樹狀圖實(shí)現(xiàn)可視化聚類詳解
一般情況下,我們都是使用散點(diǎn)圖進(jìn)行聚類可視化,但是某些的聚類算法可視化時(shí)散點(diǎn)圖并不理想,所以在這篇文章中,我們介紹如何使用樹狀圖(Dendrograms)對(duì)我們的聚類結(jié)果進(jìn)行可視化2023-03-03Python 基于Twisted框架的文件夾網(wǎng)絡(luò)傳輸源碼
這篇文章主要介紹了Python 基于Twisted框架的文件夾網(wǎng)絡(luò)傳輸源碼,需要的朋友可以參考下2016-08-08python selenium 獲取接口數(shù)據(jù)的實(shí)現(xiàn)
這篇文章主要介紹了python selenium 獲取接口數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Python實(shí)現(xiàn)批量修改文件時(shí)間屬性
我們有時(shí)候需要修改文件的“修改時(shí)間”?、?“訪問時(shí)間”,“創(chuàng)建時(shí)間”?,此時(shí)如果使用Python批量實(shí)現(xiàn)應(yīng)該會(huì)方便很多,下面小編就來為大家介紹一下具體實(shí)現(xiàn)方法吧2023-11-11