表单提交时 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
有需要的交流的可以加个好友