img标签src属性没变,改变起引用的图片,刷新页面仍然显示之前的图片

BUG描述
在做一个头像上传功能
这是前端页面的相关代码

<div class="portrait"><%="<img src=\"/user/portrait/"%><jsp:getProperty name="user" property="portrait"/><%=".jpg\" class=\"portraitPic\" id=\"portraitPic\">"%></div>

此代码绑定了onclick事件,当点击图片时,会跳转到另一个页面,此页面时用来上传图片的,代码如下

<!DOCTYPE html>
    <head>
        <meta charset="GB2312">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>图像处理</title>
        <link rel="stylesheet" href="mui/mui.css" />
        <link rel="stylesheet" href="common/common.css" />
        <link rel="stylesheet" href="dist/image-clip.css" />
        <link rel="stylesheet" href="common/clip.css" />
    </head>

    <body>
        <div class="clip-content">
            <div class="upload-container choose-gallery">
                <form class="upload-pretty button-three-dimen" method="POST" enctype="multipart/form-data" action="/user/upLoadPortraitServlet" id="picForm">
                    <input type="file" id="targetImg" name="uploadfile">本地上传
                </form>
            </div>
            <div class="upload-container choose-camera">
                <div class="upload-pretty button-three-dimen">
                    <input type="file" id="targetImgCamera" capture="camera">手机拍摄
                </div>
            </div>

            <div class="img-clip"></div>

            <nav class="clip-action nav-bar nav-bar-tab hidden">
                <a class="tab-item" id="btn-reload">
                    <span class="mui-icon mui-icon-arrowleft tab-icon"></span>
                    <span class="tab-label hidden">取消</span>
                </a>
                <a class="tab-item " id="btn-rotate-anticlockwise">
                    <span class="mui-icon mui-icon-refreshempty tab-icon rotate90"></span>
                    <span class="tab-label hidden">逆时针旋转</span>
                </a>
                <a class="tab-item " id="btn-rotate-clockwise">
                    <span class="mui-icon mui-icon-refreshempty tab-icon"></span>
                    <span class="tab-label hidden">顺时针旋转</span>
                </a>
                <a class="tab-item hidden" id="btn-maxrect">
                    <span class="mui-icon mui-icon-navigate tab-icon"></span>
                    <span class="tab-label hidden">最大选择</span>
                </a>
                <a class="tab-item" id="btn-verify">
                    <span class="mui-icon mui-icon-checkmarkempty tab-icon"></span>
                    <span class="tab-label hidden">确定</span>
                </a>
            </nav>
        </div>

        <div class="show-content hidden">
            <div class="img-wrap">
                <img class="show-img" data-preview-src="" data-preview-group="2"></img>
            </div>

            <nav class="nav-bar nav-bar-tab">
                <a class="tab-item" id="btn-back">
                    <span class="mui-icon mui-icon-arrowleft tab-icon"></span>
                    <span class="tab-label hidden">取消</span>
                </a>
                <a class="tab-item" id="btn-detail">
                    <span class="mui-icon mui-icon-more-filled tab-icon"></span>
                    <span class="tab-label hidden">详情</span>
                </a>
                <a class="tab-item" id="btn-save">
                    <span class="mui-icon mui-icon-checkmarkempty tab-icon"></span>
                    <span class="tab-label hidden">确定</span>
                </a>
            </nav>
        </div>
        <script type="text/javascript" src="common/fileinput.js"></script>
        <script type="text/javascript" src="common/exif.js"></script>
        <script type="text/javascript" src="dist/image-clip.js"></script>
        <script>
            var chooseGallery;
            var chooseCamera;
            var cropImage;
            var imgData;
            var clipContent;
            var clipAction;
            var showContent;
            var showImg;
            var targetImg;
            var targetImgCamera;

            initPage();

            function initPage() {
                initParams();
                initListeners();
                initImgClip();
            }

            function initParams() {
                targetImg = document.querySelector('#targetImg');
                targetImgCamera = document.querySelector('#targetImgCamera');
                chooseGallery = document.querySelector('.choose-gallery');
                chooseCamera = document.querySelector('.choose-camera');
                clipContent = document.querySelector('.clip-content');
                clipAction = document.querySelector('.clip-action');
                showContent = document.querySelector('.show-content');
                showImg = document.querySelector('.show-img');
            }

            function initImgClip() {
                new FileInput({
                    container: '#targetImg',
                    isMulti: false,
                    type: 'Image_Camera',
                    success: function(b64, file, detail) {
                        // console.log("选择:" + b64);
                        console.log("fileName:" + file.name);

                        loadImg(b64);
                    },
                    error: function(error) {
                        console.error(error);
                    }
                });
                new FileInput({
                    container: '#targetImgCamera',
                    isMulti: false,
                    type: 'Camera',
                    success: function(b64, file, detail) {
                        // console.log("选择:" + b64);
                        console.log("fileName:" + file.name);
                        loadImg(b64);
                    },
                    error: function(error) {
                        console.error(error);
                    }
                });
            }

            function loadImg(b64) {
                changeImgClipShow(true);

                var img = new Image();
                img.src = b64;

                img.onload = function() {
                    EXIF.getData(img, function() {
                        var orientation = EXIF.getTag(this, 'Orientation');

                        cropImage && cropImage.destroy();
                        cropImage = new ImageClip({
                            container: '.img-clip',
                            img,
                            // 0代表按下才显示,1恒显示,-1不显示
                            sizeTipsStyle: 0,
                            // 为1一般是屏幕像素x2这个宽高
                            // 最终的大小为:屏幕像素*屏幕像素比(手机中一般为2)*compressScaleRatio
                            compressScaleRatio: 1.1,
                            // iphone中是否继续放大:x*iphoneFixedRatio
                            // 最好compressScaleRatio*iphoneFixedRatio不要超过2
                            iphoneFixedRatio: 1.8,
                            // 减去顶部间距,底部bar,以及显示间距
                            maxCssHeight: window.innerHeight - 100 - 50 - 20,
                            // 放大镜捕获的图像半径
                            captureRadius: 30,
                            // 是否采用原图像素(不会压缩)
                            isUseOriginSize: false,
                            // 增加最大宽度,增加后最大不会超过这个宽度
                            maxWidth: 0,
                            // 是否固定框高,优先级最大,设置后其余所有系数都无用直接使用这个固定的宽,高度自适应
                            forceWidth: 0,
                            // 同上,但是一般不建议设置,因为很可能会改变宽高比导致拉升,特殊场景下使用
                            forceHeight: 0,
                            // 压缩质量
                            quality: 0.92,
                            mime: 'image/jpeg',
                        });

                        // 6代表图片需要顺时针修复(默认逆时针处理了,所以需要顺过来修复)
                        switch (orientation) {
                            case 6:
                                cropImage.rotate(true);
                                break;
                            default:
                                break;
                        }

                    });
                };
            }

            function resizeShowImg(b64) {
                var img = new Image();

                img.src = b64;
                img.onload = showImgOnload;
            }

            function showImgOnload() {
                // 必须用一个新的图片加载,否则如果只用showImg的话永远都是第1张
                // margin的话由于有样式,所以自动控制了
                var width = this.width;
                var height = this.height;
                var wPerH = width / height;
                var MAX_WIDTH = Math.min(window.innerWidth, width);
                var MAX_HEIGHT = Math.min(window.innerHeight - 50 - 100, height);
                var legalWidth = MAX_WIDTH;
                var legalHeight = legalWidth / wPerH;

                if (MAX_WIDTH && legalWidth > MAX_WIDTH) {
                    legalWidth = MAX_WIDTH;
                    legalHeight = legalWidth / wPerH;
                }
                if (MAX_HEIGHT && legalHeight > MAX_HEIGHT) {
                    legalHeight = MAX_HEIGHT;
                    legalWidth = legalHeight * wPerH;
                }

                var marginTop = (window.innerHeight - 50 - legalHeight) / 2;

                showImg.style.marginTop = marginTop + 'px';
                showImg.style.width = legalWidth + 'px';
                showImg.style.height = legalHeight + 'px';
            }

            function changeImgClipShow(isClip) {
                if (isClip) {
                    chooseGallery.classList.add('hidden');
                    chooseCamera.classList.add('hidden');
                    clipAction.classList.remove('hidden');
                } else {
                    chooseGallery.classList.remove('hidden');
                    chooseCamera.classList.remove('hidden');
                    clipAction.classList.add('hidden');
                    // 需要改变input,否则下一次无法change
                    targetImg.value = '';
                    targetImgCamera.value = '';
                }
            }

            function initListeners() {
                document.querySelector('#btn-reload').addEventListener('click', function() {
                    cropImage && cropImage.destroy();
                    changeImgClipShow(false);
                });
                document.querySelector('#btn-back').addEventListener('click', function() {
                    changeContent(false);
                });
                document.querySelector('#btn-save').addEventListener('click', function() {
                    // downloadFile(imgData);
                    upload(function() {
                        document.getElementById("picForm").submit();
                        tips('上传成功');
                    });
                });
                document.querySelector('#btn-detail').addEventListener('click', function() {
                    showImgDataLen(imgData);
                });

                document.querySelector('#btn-maxrect').addEventListener('click', function() {
                    if (!cropImage) {
                        tips('请选择图片');
                        return;
                    }
                    cropImage.resetClipRect();
                });

                document.querySelector('#btn-rotate-anticlockwise').addEventListener('click', function() {
                    if (!cropImage) {
                        tips('请选择图片');
                        return;
                    }
                    cropImage.rotate(false);
                });

                document.querySelector('#btn-rotate-clockwise').addEventListener('click', function() {
                    if (!cropImage) {
                        tips('请选择图片');
                        return;
                    }
                    cropImage.rotate(true);
                });

                document.querySelector('#btn-verify').addEventListener('click', function() {
                    if (!cropImage) {
                        tips('请选择图片');
                        return;
                    }

                    var isConfirm = confirm("是否裁剪图片并处理?");

                    if (isConfirm) {
                        cropImage.clip(false);
                        imgData = cropImage.getClipImgData();
                        recognizeImg(function() {
                            changeContent(true);
                        }, function(error) {
                            tips(JSON.stringify(error), true);
                        });
                    }

                });
            }

            function showImgDataLen(imgData) {
                var len = imgData.length;
                var sizeStr = len + 'B';

                if (len > 1024 * 1024) {
                    sizeStr = (Math.round(len / (1024 * 1024))).toString() + 'MB';
                } else if (len > 1024) {
                    sizeStr = (Math.round(len / 1024)).toString() + 'KB';
                }

                tips('处理后大小:' + sizeStr);
            }

            function tips(msg, isAlert) {
                if (isAlert) {
                    alert(msg);
                } else {
                    toast(msg);
                }
            }

            function toast(message) {
                var CLASS_ACTIVE = 'mui-active';
                var duration = 2000;
                var toastDiv = document.createElement('div');

                toastDiv.classList.add('mui-toast-container');
                toastDiv.innerHTML = `<div class="mui-toast-message">${message}</div>`;
                toastDiv.addEventListener('webkitTransitionEnd', () => {
                    if (!toastDiv.classList.contains(CLASS_ACTIVE)) {
                        toastDiv.parentNode.removeChild(toastDiv);
                        toastDiv = null;
                    }
                });
                // 点击则自动消失
                toastDiv.addEventListener('click', () => {
                    toastDiv.parentNode.removeChild(toastDiv);
                    toastDiv = null;
                });
                document.body.appendChild(toastDiv);
                toastDiv.classList.add(CLASS_ACTIVE);
                setTimeout(function() {
                    toastDiv && toastDiv.classList.remove(CLASS_ACTIVE);
                }, duration);
            }

            function changeContent(isShowContent) {
                if (isShowContent) {
                    showContent.classList.remove('hidden');
                    clipContent.classList.add('hidden');

                    resizeShowImg(imgData);
                    showImg.src = imgData;

                } else {
                    showContent.classList.add('hidden');
                    clipContent.classList.remove('hidden');
                }
            }

            function b64ToBlob(urlData) {
                var arr = urlData.split(',');
                var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
                // 去掉url的头,并转化为byte
                var bytes = window.atob(arr[1]);

                // 处理异常,将ascii码小于0的转换为大于0
                var ab = new ArrayBuffer(bytes.length);
                // 生成视图(直接针对内存):8位无符号整数,长度1个字节
                var ia = new Uint8Array(ab);
                for (var i = 0; i < bytes.length; i++) {
                    ia[i] = bytes.charCodeAt(i);
                }

                return new Blob([ab], {
                    type: mime
                });
            }

            function downloadFile(content) {
                // Convert image to 'octet-stream' (Just a download, really)
                var imageObj = content.replace("image/jpeg", "image/octet-stream");
                window.location.href = imageObj;
            }

            function recognizeImg(success, error) {
                // 里面正常有:裁边,摆正,梯形矫正,锐化等算法操作
                success();
            }

            function upload(success, error) {
                success();
            }
        </script>
    </body>

</html>

后台保存图片到服务端是使用jspsmartupload组件,代码如下

package user;

import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;
import database.DBOperate;

import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Calendar;
import java.util.Random;

@WebServlet(name = "UpLoadPortraitServlet", urlPatterns = "/user/upLoadPortraitServlet")
public class UpLoadPortraitServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getSession().getAttribute("id").toString();
        SmartUpload su = new SmartUpload();
        su.initialize(this.getServletConfig(), request, response);
        try {
            su.upload();
            su.setAllowedFilesList("jpg,png");
            String path = "D:\\IdeaProjects\\CampusAddressList\\web\\user\\portrait\\pic_"
                    + id + ".jpg";
//            String path = "/user/portrait/pic_" + id + ".jpg";
            su.getFiles().getFile(0).saveAs(path);
            DBOperate.changePortrait(id);
            RequestDispatcher rd = request.getRequestDispatcher("/user/user.jsp");
            rd.forward(request, response);
        } catch (SmartUploadException e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

这时候出现了一个问题,就是我上传完图片后,在我的IDE(IDEA)是可以看到图片上传成功且改变了的,但是页面进行刷新却是显示原先的图片。如果我重启tomcat服务器的话,改动就可以在页面显示出来。

解决方法
一开始以为是由于浏览器缓存了图片,所以在src属性的链接后面加上一个随机数,以防止浏览器读取缓存,而不是新的图片。但是没用。之后我页面设置了该页面不能缓存,但也没用。在我在绝望的时候,我对上传代码的路径改动了一下,发现却修复了这个bug。改动如下,

String path = "D:\\IdeaProjects\\CampusAddressList\\web\\user\\portrait\\pic_" + id + ".jpg";

改为

String path = "/user/portrait/pic_" + id + ".jpg";

至于为什么改动完之后就可以了,希望评论可以指导一下。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值