1. 程式人生 > >vue-resource post資料時碰到Django csrf

vue-resource post資料時碰到Django csrf

公司最近用vue寫前端,用vue-resource遇到的一些問題,現在記錄下來。

vue-resource post資料

this.$http.post('/someUrl',data, [options]).then(function(response){
    // 響應成功回撥
}, function(response){
    // 響應錯誤回撥
});

vue-resource 向後端請求api, 公司的後臺是用Django 開發的,Django為了防止跨站請求偽造,即csrf攻擊,提供了CsrfViewMiddleware中介軟體來防禦csrf攻擊。

我們在html 頁面里加入{% csrf %}

來讓django渲染出一個csrf的標籤
(如果是form 提交表單的話,我們要把這個標籤加在form標籤內,如果是用xhr提交的話寫在html頁面裡就可以了)

不寫在form 表單內,但是實現效果是一樣的,我們都需要在post 的表單中提供csrftoken我們在vue裡要傳送的的data 裡要加上csrf的key

data{
    csrfmiddlewaretoken: '{{ csrf_token }}' 
}

這樣django解析表單時會解析到csrf_token, 我們post的資料就不會遇到403 forbidden了。

其實這樣是投機取巧的行為,這樣雖然django 也能識別,但是遇到複雜的資料時就不行了,比如陣列,vue-resource post 陣列的時候, 因為我之前在post的option里加了一個option {emulateJSON: true},這樣vue-resource 在post資料時,會把data 轉換成 application/x-www-form-urlencoded

表單格式,但是這樣的話,post 的陣列就會被解析成arrry[0]item 這樣的話,後端是不識別的,會報錯。

解決方式查到是把csrftoken 放在報頭裡,data 傳資料,具體解決方式是加一條

Vue.http.headers.common['X-CSRFToken'] = $("input[name='csrfmiddlewaretoken']").val()

其中$("input[name='csrfmiddlewaretoken']").val() 是取django 的{% csrf %}在模板解析後生成的input裡的csrftoken。

其中報頭的話django 在後臺解析的時候會自動加上HTTP_

的字首,所以說我們的報頭是 X-CSRFToken就可以了。