zoukankan      html  css  js  c++  java
  • 纠结的上传控件,啊!多么痛的领悟

    如果那写错了,或者那写的不对路子请帮忙说出来,我好改正,嘿嘿进步都是一点点的哟!~

    正文之前

    搞不清楚是上传控件的脑残还是我下午脑袋缺氧。这种情况搞不懂是不是常见的形态之一了。

    正文之前结束

    今天阳光明媚(摔!风很大!),抱着愉悦的心情来等待测试的bug。我个人很有信心木有bug(摔!MB俩模块测试出6个BUG)。没想到第一个BUG出来了。而这个BUG也是这个文章的略点,就不说了,当第3个BUG出来的时候我才知道,今天下午是灾难性的。

    问题出现在上传控件上,为了跟后端友好的交互果断拖了个上传控件。客户需求是当点击上传控件的浏览的时候

    就是下图

    要显示这个图片,当然这个图片是不上传的话是极好的(摔!)

    好吧,抱着客户是上帝的想法我果断的写出了如下的JS代码

      $(function () {
                $("#fileupImg").change(function () {
                    var turl = $("#XXOO").val().replace(':\\', '^').split('^')[1];
                    var location = "file:///" + turl;
                    var type = location.substr(location.lastIndexOf(".")).toLowerCase();
                    var img = new Image();
                    
                    if (type == ".jpg" || type == ".gif" || type == ".jpeg" || type == ".bmp") {
                        img.src = location;
                        img.onload = function () {
                            if (img.width < 1355 || img.width >= 1365) {
                                alert("上传图片的宽度要在1355到1365像素之间");
                                return;
    
                            }
                            if (img.height < 1015 || img.height > 1025) {
                                alert("上传图片的高度要在1015到1025像素之间");
                                return;
                            }
                            $("#yiku").attr("src", location);
                            $("#yiku").show();
                  
                        }
                    } else {
                        alert("图片格式不对!");
                    }
                })
            });
    

      这段代码在编写阶段的时候是木有问题的(TMD,当时老子要测试下盘符可否显示就好了)

      在桌面上传图片的时候什么问题都没有,当然也可能出现问题,这个一会在说。

    测试人员告诉我,上传的图片不显示。我就好奇为什么呢,找她要一下测试图片,自己测试下发现,连桌面的都无法显示,并且看到的源码并不是跟我设想的一样。这个时候我就在考虑原因是什么,首先进入脑帘的就是,权限问题。

    浏览器是否有权限读写用户的硬盘信息,换种说法JS是否有权限操作硬盘信息?我想应该是没有,但是为什么本地的源码就可以获取到桌面的图片呢,我想大概是因为我在本地测试,本地预览有关系,希望知道的大牛帮我解答下这个问题。

    时间一分一秒的过去了,突然想到,这个方法如果不行怎么办。有的观众会说了用第三方啊。亲,第三方是不让用的,并且我还需要知道他上传图片的尺寸,在上面的代码你们也看到了我需要判断尺寸来决定是否上传。这时候,我想起了亲爱的谷歌。在谷歌上搜索无数个关键字,终于找到一个关键字,滤镜。

    JS还有滤镜?这个是我头一次听说,难道美图秀秀是用JS写的?

    谷歌的办法无非就是通过滤镜来把图片加载到,我窃喜,终于找到解决办法了!上代码!~

                imgDiv.style.width="必填";
                imgDiv.height="必填";                   
     imgDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod = scale)";
                        imgDiv.get(0).filters.item("DXImageTransform.Microsoft.AlphaImageLoader").sizingMethod = "image";
    

      这个是关键代码。经过测试,这个代码在浏览器安全级别很低的情况下可用,如果您的客户浏览器安全级别很低,可以使用这段话。

    网上是 sizingmethod=scale; 这么写我的没有分号,如果有分号那么他容器就会失效,搞不懂网上为什么都这么写。容器失效的后果就是图片出来之后是原尺寸。

    当然,我说了这个是在浏览器安全级别很低的情况下没问题,而默认的浏览器安全级别都是 中或者是中-高。

    这样就涉及到一个属性

    这个属性,他会让你的上传控件路径变成 X:\fakepath\文件名,你们看到了他把真实路径给掩盖了(浏览器掩盖了事实的真相!!!)。查到的相关资料大意是因为浏览器需要安全,从IE7开始路径就给安全化了。

    那么怎么办呢。我们可以在获取 物理路径的时候写上

    下面这段话

                var file = document.getElementById('XXOO');
                file.select();
                file.blur();
      var a= document.selection.createRange().text;

      这样就能获取到真实的路径了,然后就可以做你想做的事情了,这样上面的浏览器安全级别低的那段代码也就可以用了(我没测试,但是应该没问题)。

    接下来我要面对的是另一个问题,图片我获取不到他的宽度和高度。当然有的客官说了,你都获取到真实地址了怎么能获取不到宽度高度呢,我没测试,但是应该不能,在IE7之后的安全策略里面,现在是不让获取本地文件属性的。

    到这个时候已经是临近下班的点了,我还想下班回家玩XBOX呢。没办法只能把情况如实的反应一下,后来要求我限期整改,选择图片的时候可以上传但是木有上传按钮,页面不能刷新,当然这都是简单的解决(啊?你不会?我没办法了动脑想一下就能解决)。

    最终解决方案是上传一张图片。

    有的人也问了,为什么当初设计的时候不让上传呢?因为我们这个上传还涉及到很多东西,综合下来如果上传一次的话性能下降很多,要做大量的IO读写。而现的上传是上传到临时的文件夹里面,当确定这条数据的时候删除临时文件夹里面的这一个文件,而非多次IO读写。性能提高一些。

    当搞定这些问题的时候已经是快9点了。后面几个BUG都是哭笑不得的疏忽,这样的疏忽,让我老脸通红。。

    下午学到了这些知识,我觉得很不错了,至少知道了 IE浏览器的安全策略和几个上传的方法。

    今天是多么美好的一天那。

    以上代码是IE 7 8 9未测试 其他浏览器。

    PS:还有一种是HTML5的方式也很有意思,这个是群里的朋友帮我提供的。

     1 <style>
     2   .thumb {
     3     height: 75px;
     4     border: 1px solid #000;
     5     margin: 10px 5px 0 0;
     6   }
     7 </style>
     8 
     9 <input type="file" id="files" name="files[]" multiple />
    10 <output id="list"></output>
    11 
    12 <script>
    13   function handleFileSelect(evt) {
    14     var files = evt.target.files; // FileList object
    15 
    16     // Loop through the FileList and render image files as thumbnails.
    17     for (var i = 0, f; f = files[i]; i++) {
    18 
    19       // Only process image files.
    20       if (!f.type.match('image.*')) {
    21         continue;
    22       }
    23 
    24       var reader = new FileReader();
    25 
    26       // Closure to capture the file information.
    27       reader.onload = (function(theFile) {
    28         return function(e) {
    29           // Render thumbnail.
    30           var span = document.createElement('span');
    31           span.innerHTML = ['<img class="thumb" src="', e.target.result,
    32                             '" title="', escape(theFile.name), '"/>'].join('');
    33           document.getElementById('list').insertBefore(span, null);
    34         };
    35       })(f);
    36 
    37       // Read in the image file as a data URL.
    38       reader.readAsDataURL(f);
    39     }
    40   }
    41 
    42   document.getElementById('files').addEventListener('change', handleFileSelect, false);
    43 </script>


    作者:小胖李
    出处:http://www.cnblogs.com/minCS/
    本文版权归作者和博客园共有,禁止转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

     

  • 相关阅读:
    JS阻止鼠标滚动
    仿淘宝订单列表下标指针
    自己动手模拟百分百<select>下拉列表
    专门用来存地址
    JS手动触发事件,转载
    刷新页面让显示区域回到顶部
    解决表格边框问题
    读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字
    读书笔记 effective c++ Item 42 理解typename的两种涵义
    读书笔记 effective c++ Item 41 理解隐式接口和编译期多态
  • 原文地址:https://www.cnblogs.com/minCS/p/3091481.html
Copyright © 2011-2022 走看看