我正在使用Plupload js插件在一个请求中上传多个图片。这个插件的工作方式就像有人一次添加5个图像一样,发布请求将会分别上传每个图像5次。我们知道Post请求需要唯一的csrf令牌,但在我的情况下由于相同的令牌一次后,post请求失败。
这是我的代码......
<c:set var="csrfTokenVal"><csrf:token-value uri="<%=request.getRequestURI()%>"/></c:set>
<script>
var csrftokenV="${csrfTokenVal}";
$("#uploader").plupload({
// General settings
runtimes : 'html5,flash,silverlight,html4',
url:'/view/SurgeryNotesComponentController?uploadSurgeryImage=true&'+csrftokenN+'='+csrftokenV,
// User can upload no more then 20 files in one go (sets multiple_queues to false)
max_file_count: 10,
chunk_size: '1mb',
// Resize images on clientside if we can
resize : {
width : 600,
height : 610,
quality : 90,
//crop: true // crop to exact dimensions
},
filters : {
// Maximum file size
max_file_size : '1mb',
// Specify what files to browse for
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Rename files by clicking on their titles
rename: true,
// Sort files
sortable: true,
// Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
dragdrop: true,
// Views to activate
views: {
list: true,
thumbs: false, // Show thumbs
active: 'thumbs'
},
init: {
FilesAdded: function(up, files) {
$("#uploader_filelist").show();
},
FileUploaded: function(up, file, info, res) {
var imageObjectArray=$.parseJSON(info.response);
for(i=0;i<imageObjectArray.objectList.length; i++){
$('#showfilelist ul').append("<li><a class='delIcon-image' href='#delete' id='delSurgeryImageIcon'></a><a id=" + imageObjectArray.objectList[i].uid + " class='cboxElement imguid' href='${contextPath}/view/SurgeryNotesComponentController?surgeryImage=true&"+csrftokenN+ "="+ csrftokenV+"&attachmentLocation="+imageObjectArray.objectList[i].attachmentLocation+"' target='_blank'><img src='${contextPath}/view/SurgeryNotesComponentController?surgeryImage=true&"+csrftokenN+ "="+ csrftokenV+"&attachmentLocation="+imageObjectArray.objectList[i].attachmentLocation+"' border='0'>"+"</a> <strong>"+noteAddedMsg+"</strong><span class='image-created'>"+imageObjectArray.objectList[i].formattedDate+" "+byMsg+" "+imageObjectArray.objectList[i].userName+" </span></li>");
}
$("#uploader_filelist").empty().hide();
_SPINE.colorboxOverlay.coloboxPopup();
_SPINE.surgeryNotes.deleteImages();
$(".plupload_done .plupload_file_thumb").removeClass("hide")
},
ChunkUploaded: function (up, file, response) {
response = $.parseJSON(response.response || "null");
if (response.chunk == 3) {
up.stop();
up.start();
}
console.log(file.loaded);
}
},
// Flash settings
flash_swf_url : '${siteAssetsUrl}/assets/spine/js/external/Moxie.swf',
// Silverlight settings../assets/js
silverlight_xap_url : '${siteAssetsUrl}/assets/spine/js/external/Moxie.xap'
});
</script>
在这里你可以看到我正在生成scrf令牌(csrftokenV)并在url中发送它以使其支持发布。
现在的问题是,如果我上传的图片超过1张(比方说3张),那么3个帖子后请求就会出现。每次我都会得到相同的csrf令牌,并在上传第一张图片后,不能使用的图片不会有效,我会得到这个例外....
WARNING: potential cross-site request forgery (CSRF) attack thwarted (user:<anonymous>, ip:127.0.0.1, uri:/**/image, error:request token does not match session token)
请帮我解决这个问题。感谢
答案 0 :(得分:0)
最后我的一位朋友解决了这个问题。通过客户端脚本处理此问题是不可能的,因此我们利用Java的强大功能。我们已根据新请求更新了csrfToken,并将其与响应一起发送出去。
这是一个解决方案..
private String updateToken(HttpServletRequest request)
{
final HttpSession session = request.getSession(false);
CsrfGuard csrfGuard = CsrfGuard.getInstance();
csrfGuard.updateTokens(request);
String newToken=(String) session.getAttribute(REQUEST_TOKEN);
return newToken;
}
在响应中设置newToken ...
response.setResult(this.updateToken(request));
return response;
现在我们可以更改beforeUpload事件中的url并在url中设置新令牌。
BeforeUpload: function(up, file)
{
up.settings.url='/view/SurgeryNotesComponentController?uploadSurgeryImage=true&'+csrftokenN+'='+tokenRefresh
}
FileUploaded: function(up, file, info, res)
{
var imageObjectArray=$.parseJSON(info.response);
tokenRefresh=imageObjectArray.result;
}