在项目中经常用到input标签来上传文件,而这些文件通常是图片文件。图片有很多格式我们只需要其中的几种,就需要对用户上传的文件进行验证,在HTML5中有一个新的属性:accept文件类型限制。但是通常我们会用javascript或jQuery编写方法进行验证图片的大小限制、类型判断、像素判断。

<input type="file" name="files" id="file" οnchange="verificationPicFile(this)">
1.
//图片类型验证
function verificationPicFile(file) {
    var fileTypes = [".jpg", ".png"];
    var filePath = file.value;
    //当括号里面的值为0、空字符、false 、null 、undefined的时候就相当于false
    if(filePath){
        var isNext = false;
        var fileEnd = filePath.substring(filePath.indexOf("."));
        for (var i = 0; i < fileTypes.length; i++) {
            if (fileTypes[i] == fileEnd) {
                isNext = true;
                break;
            }
        }
        if (!isNext){
            alert('不接受此文件类型');
            file.value = "";
            return false;
        }
    }else {
        return false;
    }
}

//图片大小验证
function verificationPicFile(file) {
    var fileSize = 0;
    var fileMaxSize = 1024;//1M
    var filePath = file.value;
    if(filePath){
        fileSize =file.files[0].size;
        var size = fileSize / 1024;
        if (size > fileMaxSize) {
            alert("文件大小不能大于1M!");
            file.value = "";
            return false;
        }else if (size <= 0) {
            alert("文件大小不能为0M!");
            file.value = "";
            return false;
        }
    }else{
        return false;
    }
}

//图片尺寸验证
function verificationPicFile(file) {
    var filePath = file.value;
    if(filePath){
        //读取图片数据
        var filePic = file.files[0];
        var reader = new FileReader();
        reader.onload = function (e) {
            var data = e.target.result;
            //加载图片获取图片真实宽度和高度
            var image = new Image();
            image.οnlοad=function(){
                var width = image.width;
                var height = image.height;
                if (width == 720 | height == 1280){
                    alert("文件尺寸符合!");
                }else {
                    alert("文件尺寸应为:720*1280!");
                    file.value = "";
                    return false;
                }
            };
            image.src= data;
        };
        reader.readAsDataURL(filePic);
    }else{
        return false;
    }
}

@n0099 请问您设置的参数是多大
已知图片大小是2m
类型不支持哪些未知
像素长宽限制未知

代码我随便偷的 您别吐槽


有无必要部署类似于微信头像这种自动压缩节约服务器空间功能

积分: 2

    Viennahl2rd 请问您设置的参数是多大
    已知图片大小是2m
    类型不支持哪些未知
    像素长宽限制未知

    我没设过,flarum又不是我写的

    Viennahl2rd 代码我随便偷的 您别吐槽

    我都不知道您从不知道csdn还是哪儿复制粘贴一坨js代码来在前端过滤上传图片的实现干嘛

    Viennahl2rd 有无必要部署类似于微信头像这种自动压缩节约服务器空间功能

    flarum本身就会压头像分辨率到100x100

      根据四叶tg群与 @Wien 的讨论结果:

      n0099 我没设过,flarum又不是我写的

      结合flarum有关源码 https://github.com/flarum/framework/blob/main/framework/core/src/User/AvatarValidator.php
      我的总结是提前v吧前前吧主BSDS集团阁下将您无法上传的图片原图以任意途径渠道发给我以便彻查其背后的原因

        n0099 确实如此 上传成功后再下载就是100•100

        彗星の如く現れた星の原石

        アイドルvtuberほしまちすいせい☄~

        すいちゃんは——今日もかわいい!

        No life must forced to stop

        积分: 18

        n0099 盼羊归😭

        彗星の如く現れた星の原石

        アイドルvtuberほしまちすいせい☄~

        すいちゃんは——今日もかわいい!

        No life must forced to stop

        积分: 18

        BSDS集团 所以您为什么不直接采用已经压缩完毕的100×100或者是尝试类似于这个107×111的等比例略缩

        彗星の如く現れた星の原石

        アイドルvtuberほしまちすいせい☄~

        すいちゃんは——今日もかわいい!

        No life must forced to stop

          BSDS集团 您即便上传后也是这个效果 因为头像最后本身就是100×100显示
          不如直接用之后的

          彗星の如く現れた星の原石

          アイドルvtuberほしまちすいせい☄~

          すいちゃんは——今日もかわいい!

          No life must forced to stop

          积分: 18

          BSDS集团
          @n0099 对此早已有所预言:会webp压缩
          图片目前大小为106Kb
          所以还是得上传原文件到定向图床 亦或是压缩包还原形式
          以及您的图片应该也不是最原始的图
          一般来说数位板绘制的原图产出至少都是几M

          彗星の如く現れた星の原石

          アイドルvtuberほしまちすいせい☄~

          すいちゃんは——今日もかわいい!

          No life must forced to stop

          积分: 18

            Wien 他只要上传到本坛了就行了
            我可以去拿到转webp之前他上传的图片文件

            Wien 以及您的图片应该也不是最原始的图
            一般来说数位板绘制的原图产出至少都是几M

            现在问题的核心是获得

            n0099 您无法上传的图片原图

            这样我才有可能复现问题,而不是获得画师的原图

            积分: 15

            Wien 图片目前大小为106Kb

            事实核查:他上传的原图也只有

            $ file 1667113773-811898-1666748230997.jpg
            1667113773-811898-1666748230997.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 96x96, segment length 16, comment: "CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90", baseline, precision 8, 1696x1718, components 3

              n0099 事实是这样
              上传如果是直接最大裁剪 那自然不行

              然后变小一点就行了
              所以还是原图像素点数量的问题,超过了函数的上限

              以及这只是 个人对于裁剪的问题 想要保留完整性 所以刻意将圆形裁剪显示拉到最大
              QQ tieba 微信当然随便这么玩 因为服务器自动压缩为纵横的一两百原比例像素
              就像qq头像表面上是圆形 实际上还是方形吧 如果直接拉到近似于最大 那等于没裁
              那像素点这么多肯定不满足啊

              彗星の如く現れた星の原石

              アイドルvtuberほしまちすいせい☄~

              すいちゃんは——今日もかわいい!

              No life must forced to stop

              积分: 18

                Wien qq头像表面上是圆形 实际上还是方形吧

                大多数圆形头像都是在显示的地方做裁剪,而不是服务端实际存储的头像图片是圆形(至于圆之外的图片边界框之内的像素是纯白还是纯黑还是png的alpha通道255(全透明)是实现细节)

                Wien 那像素点这么多肯定不满足啊

                满足什么?

                • Wien 回复了此帖
                积分: 15

                  Wien 您说的很对,但事实是这个由js实现的裁剪选区窗口输出的图片是高度原始的png,然后再把裁剪了的png传给flarum服务端

                  而当对于这张jpg,选区拖到最外面后其产生的png大小是2409795字节
                  正好超过了flarum服务端硬编码的的2048kib的文件字节限制:
                  https://github.com/flarum/framework/blob/201d7430feaaace581a07b15fd1161179da441ff/framework/core/src/User/AvatarValidator.php#L100

                    进一步的事实核查:

                    n0099 由js实现的裁剪选区窗口

                    具体是指的扩展 https://github.com/FriendsOfFlarum/profile-image-crop

                    追溯上传网络请求的callstack我们可以找到

                    在这里可以看见上传网络请求的multipart/form-data的第一个文件的二进制内容来自blob变量,而blob变量又来自L90的canvas.toBlob()的返回值,根据其文档 https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob 可知由于这里没有额外参数指定使用jpg或webp压缩并提供压缩quality值导致其会直接返回没有压缩的png,这也解释了此前

                    为什么能够指png为jpg


                    事实是这问题在扩展用户之中早有预言:
                    https://discuss.flarum.org/d/18286/28
                    https://github.com/FriendsOfFlarum/profile-image-crop/issues/15
                    并早已有人修复了这个问题并在3个月前其pr被merge
                    https://github.com/FriendsOfFlarum/profile-image-crop/pull/17
                    但不幸地

                    由浏览器扩展 https://github.com/refined-github/refined-github 向我提醒的

                    The merge commit doesn’t appear in any tags

                    意味着截止2022年11月,这个pr所造成的更改仍未反映在任何github tags及对应的packagist包版本之中
                    目前这个扩展的最新版本是去年11月发布的1.0.1,其对应的github tags和commit是 https://github.com/FriendsOfFlarum/profile-image-crop/commits/master#:~:text=Remove%20Bazaar%20reference

                    对于此问题我已致电该扩展repo的有关人士催促其进行一个包流程的发布: https://github.com/FriendsOfFlarum/profile-image-crop/pull/17#issuecomment-1296220944

                      n0099 满足小于2m字节上限

                      彗星の如く現れた星の原石

                      アイドルvtuberほしまちすいせい☄~

                      すいちゃんは——今日もかわいい!

                      No life must forced to stop

                      积分: 18

                      n0099 真•对症下药

                      彗星の如く現れた星の原石

                      アイドルvtuberほしまちすいせい☄~

                      すいちゃんは——今日もかわいい!

                      No life must forced to stop

                      积分: 18