vue-resource post數據
參考:https://www.cnblogs.com/linxizhifeng/p/8995077.html
閱讀django CsrfViewMiddleware源碼可知,csrftoken可以放在請求參數(csrfmiddlewaretoken)里面或者請求頭(X-CSRFToken)里:
# Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": try: request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') except IOError: # Handle a broken connection before we've completed reading # the POST data. process_view shouldn't raise any # exceptions, so we'll ignore and serve the user a 403 # (assuming they're still listening, which they probably # aren't because of the error). pass if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX, # and possible for PUT/DELETE. request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
1 this.$http.post('/someUrl',data, [options]).then(function(response){ 2 // 響應成功回調 3 }, function(response){ 4 // 響應錯誤回調 5 });
vue-resource 向后端請求api, 公司的后台是用Django 開發的,Django為了防止跨站請求偽造,即csrf攻擊,提供了CsrfViewMiddleware中間件來防御csrf攻擊。
我們在html 頁面里加入{% csrf %}
來讓django渲染出一個csrf的標簽
(如果是form 提交表單的話,我們要把這個標簽加在form標簽內,如果是用xhr提交的話寫在html頁面里就可以了)
手動生成csrftoken
1。request.META["CSRF_COOKIE_USED"] = True
2。手動調用 csrf 中的 get_token(request) 或 rotate_token(request) 方法
3。html表單帶{%csrf_token%} (適用於django render渲染的前端)
4。裝飾器ensure_csrf_cookie
不寫在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
就可以了。
另附一片參考博客地址:https://www.cnblogs.com/linxizhifeng/p/8995077.html