表單提交時 form submit 直接就可以提交了,但是了防止跨站攻擊,都可以加入CSRF來防禦。
node下的配置
var csrf = require('csurf');
app.use(csrf());
app.use(function(req, res, next){
let _csrf = req.csrfToken();
res.locals.csrf = _csrf;
res.cookie('XSRF-TOKEN', _csrf);
return next();
});
頁面
<form id="localimage" action="/login" method="POST">
<input id="csrf" type="hidden" name="_csrf" value="<%= csrf %>">
<input id="test" name="test" class="test" type="text">
</form>
這麼寫當然沒問題,但是當上傳文件就不行了。
需要設置表單的enctype屬性, 默認enctype 是對所有字符進行編碼了的,同時csrf值就不能放到input 進行提交,從csrf源碼來看我們傳輸csrf值可以放在以下幾個地方
<form id="localimage" action="/login?_csrf=<%= csrf %>" method="POST" enctype="multipart/form-data">
<input id="imguploadinput" name="upfile" class="imguploadinput" type="file" accept="image/jpeg,image/gif,image/png,image/bmp">
</form>
ajax異步提交,也是如此,但文件時也 new FormData 提交的,csrf 放在FormData 裏也不行。最好的就是放在請求頭裏
xhr.setRequestHeader('csrf-token', _csrf);
在ueditor裏就很容易做了,ueditor裏 是有ajax 方法提交的,但是沒有支持file的,使用ue的方法默認就對錶單信息進行了編碼
可以將此方法修改一下就行了
addEvent(imguploadinput, 'change', function() {
// var localImage = document.getElementById('localimage');
// localImage.submit();
var ajax = UE.ajax;
// 圖片
var file = document.getElementById('imguploadinput').files[0];
var form = new FormData();
form.append('file', file);
ajax.request('/ueditor/ue?action=uploadimage', {
method: 'POST',
timeout: 10000,
async: true,
data: form,
_csrf: csrf.value,
onsuccess: function ( xhr ) {
console.log( xhr.responseText );
},
//請求失敗或者超時後的回調。
onerror: function ( xhr ) {
alert( 'Ajax請求失敗' );
}
});
});
ueditor 可以修改如下
成功提交後 返回如下
否則 沒有設置header 時
如果設置了
xhr.setRequestHeader("Content-Type","multipart/form-data"); 也是不行的
寫死後就出現找不到Boundary(用戶分割不同的字段)的錯誤的錯誤
注意 使用jquery 的ajax 提交時 ,contentType 需要設置爲false
contentType:false
有需要的交流的可以加個好友