客户端 md5 (js) 与图像的服务器 md5 (php) 不匹配

问题描述 投票:0回答:1

在我的客户端中,用户选择要上传的照片,我们使用画布对其进行小型转换,将其大小调整为最大高度/宽度(保留纵横比)2500 像素。用户提交后,服务器将其写入文件并使用

md5_file
以文件 md5 哈希值进行响应。客户端上的 md5 与服务器返回的不匹配,我不知道为什么......

生成 md5 的 JS 库是

crypto-js
,我们使用的是 jquery,因此希望在 html 元素上看到
$
和 jquery 方法。

客户端代码是:


/** This accepts the file from either the file input or a paste event, then resizes it 
using the canvas to a max of 2500x2500px while maintaing aspect ratio. The base64 data is 
then set at the img src attribute and then an html element is added to the imageContainer */
function handleImage(file, imageContainer) {
    const reader = new FileReader();
    reader.onload = function(event) {
        const img = new Image();
        img.src = event.target.result;
        img.onload = function() {
            const maxDimension = 2500;
            let width = img.width;
            let height = img.height;

            // Resize the image if it exceeds the maximum dimensions
            if (width > maxDimension || height > maxDimension) {
                if (width > height) {
                    width = maxDimension;
                    height = (maxDimension * img.height) / img.width;
                } else {
                    height = maxDimension;
                    width = (maxDimension * img.width) / img.height;
                }
            }

            // Create a canvas element to draw the resized image
            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, width, height);

            // Convert the canvas to a data URL
            const resizedDataUrl = canvas.toDataURL(file.type);

            const imageType = file.type.split("/")[1];
            const imagePreview = $("<div class='image-preview'><div class='loadingIcon' style='display:none'></div><img src='" + resizedDataUrl + "' data-type='" + imageType + "'><span class='remove-image'><i class='far fa-times'></i></span></div>");

            imageContainer.append(imagePreview);

            imagePreview.find(".remove-image").click(function() {
                imagePreview.remove();
            });
        };
    };
    reader.readAsDataURL(file);
}

...

/** Called during the submit event, grabs the base64 image data and the filetype, generates an md5 using only the image data, and then sends to the serve. */
function uploadImages(img) {
    const imgData = img.attr('src')
    const imgHash = CryptoJS.MD5(imgData.replace(/^data:image\/(\w*);base64,/, ""));
    const imgType = img.data('type')
    $.ajax({
        url: 'files',
        data: { file: imgData, fileType: imgType},
        method: "POST",
        dataType: "JSON",
        success: function (r) {
            container.find('.loadingIcon').hide();
            // TODO: These aren't matching, need to figure out why...
            console.log(r.md5, imgHash.toString())
        }
    })
}

服务器代码是:

<?
    // this accepts the file data from the $_POST body, strips out the base64 header, and 
    // then writes the file. Then uses the md5_file function to generate the md5 and 
    // echos it back.
    $file = $_POST['file'];
    $fileType = $_POST['fileType'] ?? 'jpg';
    $targetPath = "/uploads/files/" . uniqid() . "." . $fileType;;
    $data = explode( ',', $file )[1];  // strip out the base64 header
    $imageData = base64_decode($data);
    file_put_contents($targetPath, $imageData);
    echo md5_file($targetPath);
?>

请注意,为了简洁起见,代码已被简化。

但是我在客户端生成的md5与服务器返回的md5不匹配。

有人看到我做错了什么吗?

谢谢!

php jquery md5 cryptojs
1个回答
0
投票

在 js 中,您仅对 Base64 字符串进行哈希处理,而在 php 中,您对真实文件进行哈希处理。这两件事完全不同,所以这是有道理的。如果你希望它是相同的,你必须在 js 上对缓冲区进行哈希

© www.soinside.com 2019 - 2024. All rights reserved.