Jquery : Post 上传多张图片时请求中断

Jquery : Post Request is breaking while uploading multiple images

我正在使用 Plupload js 插件在一个请求中上传多张图片。这个插件的工作方式就像有人一次添加 5 张图片,然后 post 请求将进行 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 以使其 post 受支持。

现在的问题是,如果我上传的图片超过 1 张(比如 3 张),那么 3 次 post 请求将会成功。每次我将获得相同的 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)

请帮我解决这个问题。谢谢

我的一位朋友终于解决了这个问题。不可能通过客户端脚本处理这个问题,所以我们利用 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;
           }