将基于 JavaScript 的 MD5 值传递给 PHP 的安全方法


secure method to pass javascript based md5 value to PHP

我正在尝试编写一个用于上传多个图像文件的脚本,该脚本将检查每个图像文件的 MD5 哈希 begore 上传到服务器

代码片段:

<script type="text/javascript">
var log = document.getElementById("hash_log");
var hash_array = [];
$("#screenshot").change(function() {
  handleFiles(this.files);
});
function handleFiles(files) {
    for (var i=0; i<files.length; i++) {
        var reader = new FileReader();
        reader.onload = function(event) {
            var binary = event.target.result;
            var md5_hash = calcMD5(binary).toString()
            hash_array[i]= md5_hash; // array to store hash value
            registerLog(hash_array[i]); // to show hash value, just for testing purpose
            setCookie( 'cookie_'+i, hash_array[i] ); // generate cookie in incremetal order, issue line
        };
        reader.onerror = function() {
            console.error("Could not read the file");
        };
        reader.readAsBinaryString(files.item(i));
    }
}
// for geneaarted hash values
function registerLog(str, className) {
    var elem = document.createElement("div");
    elem.innerHTML = str;
    elem.className = "alert-message" + (className ? " "  + className : "");
    log.appendChild(elem);
}
// function for setting cookies...
function setCookie(name, value) {
    var argv = setCookie.arguments;
    var argc = setCookie.arguments.length;
    var expires = (argc > 2) ? argv[2] : null;
    var path = (argc > 3) ? argv[3] : null;
    var domain = (argc > 4) ? argv[4] : null;
    var secure = (argc > 5) ? argv[5] : false;
    document.cookie = name + "=" + escape(value) + 
        ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + 
        ((path == null) ? "" : ("; path=" + path)) + 
        ((domain == null) ? "" : ("; domain=" + domain)) + 
        ((secure == true) ? "; secure" : "");
}
</script>

现在图像文件的哈希生成得很好,但是为了比较这些值以进行服务器端处理

我正在使用饼干来传递价值

现在在第 16 行,用于设置 cookie 的代码:

        setCookie( 'cookie_'+i, hash_array[i] );

所以 cookie 名称应该按增量顺序排列,例如:cookie1、cookie2、cookie3 等......但它只设置带有哈希值的 cookie3

原因:在文件读取功能中,如果生成 3 个文件,则 i 已设置为 3,因为它设置为总共没有选择上传的文件

因此,总的来说,请就如何增加cookie名称值提出解决方案。

我现在被困了 2 天,尝试了很多方法,但似乎唯一的方法是现在发布情况。.

另外:除了 cookie 或隐藏的输入变量之外,是否有更好的方法将变量值传递给 php。

循环终止后,函数级变量 i 的值为 3,这就是reader.onload函数"看到"的值。

您可以使用 Array.prototype.forEach 来避免这些范围问题。

阅读此博客文章以获取有关该主题的更多信息。

Thaks alexander,你的建议确实有效!

在这里,修补需要解决它。我正在发布它,以防万一,其他人可能会遇到类似的情况。

我们这里的问题是: onload 文件函数将 i 的计数器与所选文件总数的计数器相结合。在这种情况下,当调用以下用于设置 cookie 名称的函数时:

setCookie('cookie_'+index, element);

假设选择了 5 个文件进行上传,那么索引值已经是 5,所以现在 cookie 名称而不是按增量顺序排列,只会设置为"cookie_5"

这里的解决方案在于使用array.prototype.forEach循环函数这解决了现有索引值的范围问题。

array.forEach(参数),基本上它按顺序遍历数组的每个值

// create an empty array ck_array for entering new hash strings to it
 var ck_array = [];
// main function
function handleFiles(files) {
    for (var i=0; i<files.length; i++) {
        var reader = new FileReader();
        reader.onload = function(event) {
            var binary = event.target.result;
            var md5_hash = calcMD5(binary).toString()
            hash_array[i]= md5_hash; // array to store hash value
            registerLog(hash_array[i]); // to show hash value, just for testing purpose
            // code for array.prototype to work
            ck_array.push(md5_hash);
            if(ck_array.length == x){
                ck_array.forEach(function(element, index, array) {
                    setCookie('ck'+index+': ', element);
                });     
            }
        };
        reader.onerror = function() {
            console.error("Could not read the file");
        };
        reader.readAsBinaryString(files.item(i));
    }
}

现在,如果我们签入设置的cookie,cookie名称为ck0,ck1,ck2及其相应的md_5哈希值

这是jsfiddle:http://jsfiddle.net/madhvik/vpwLxph9/1/

PS注:在 jsfiddle 的运行代码中: 为简单起见,使用函数 randomString() 生成随机字符串,而不是调用 md5 哈希脚本。