纠结的上传控件,啊!多么痛的领悟
如果那写错了,或者那写的不对路子请帮忙说出来,我好改正,嘿嘿进步都是一点点的哟!~
正文之前
搞不清楚是上传控件的脑残还是我下午脑袋缺氧。这种情况搞不懂是不是常见的形态之一了。
正文之前结束
今天阳光明媚(摔!风很大!),抱着愉悦的心情来等待测试的bug。我个人很有信心木有bug(摔!MB俩模块测试出6个BUG)。没想到第一个BUG出来了。而这个BUG也是这个文章的略点,就不说了,当第3个BUG出来的时候我才知道,今天下午是灾难性的。
问题出现在上传控件上,为了跟后端友好的交互果断拖了个上传控件。客户需求是当点击上传控件的浏览的时候
就是下图
要显示这个图片,当然这个图片是不上传的话是极好的(摔!)
好吧,抱着客户是上帝的想法我果断的写出了如下的JS代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | $( 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开始路径就给安全化了。
那么怎么办呢。我们可以在获取 物理路径的时候写上
下面这段话
1 2 3 | var file = document.getElementById( 'XXOO' ); file.select(); file.blur();<br> 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/
本文版权归作者和博客园共有,禁止转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

依旧牛逼依旧狂依旧是个小流氓
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?