游乐游手机版
首页/前端开发/文章详情

Extjs图片上传无法预览的解决方案

时间:2026-06-15 07:01
Extjs上传图片无法预览因浏览器安全策略限制本地路径。解决方案采用微软AlphaImageLoader滤镜加载图片,需配置fileUpload:true,通过change事件捕获文件路径,正则过滤图片格式,实现在IE下预览,预览容器与上传控件id动态关联。

在Extjs开发中,图片上传预览是一个常见需求,但许多开发者会遇到一个经典陷阱:用户选择图片后,预览区域漆黑一片,没有任何显示。根本原因在于浏览器安全策略禁止直接将本地文件路径赋值给img标签的src属性。绕过这一限制的有效方案,是利用微软的AlphaImageLoader滤镜间接加载本地图片,从而实现稳定的预览效果。

具体实现步骤如下:首先配置一个带文件上传功能的表单控件,参考以下代码:

Extjs文件上传控件配置示例

{ width: 450, fileUpload: true, fieldLabel: '选择图片', items: [{ xtype: 'textfield', id: 'up_forth', name: 'up_forth', inputType: 'file', width: 300 }] }

这里的关键是必须设置fileUpload: true,否则表单提交时会出现编码错误。接下来需要一个预览容器,本例使用box组件嵌入一个div,尺寸固定为150×150像素:

预览容器配置代码

{ columnWidth: .18, bodyStyle: ' margin:4px 10px 10px 5px', layout: 'form', items: [{ xtype: 'box', autoEl: { width: 150, height: 150, tag: 'div', id: 'browser_up_forth' } }] }

预览容器的id与上传控件的id存在对应关系——上传控件id为up_forth,则容器id为browser_up_forth,后续函数中将基于此规则动态拼接生成完整id。

核心实现逻辑封装在下面的preview函数中。调用时需传入两个参数:外层FormPanel以及上传控件的id,例如preview(myform, 'up_forth')。特别要注意绑定时机:应在FormPanel的render事件内为上传控件添加change监听,确保控件渲染完成后才挂载事件。

预览核心函数实现

var preview = function (myform, control_id) { var img_reg = /.([jJ][pP][gG]){1}$|.([jJ][pP][eE][gG]){1}$|.([gG][iI][fF]){1}$|.([pP][nN][gG]){1}$|.([bB][mM][pP]){1}$/ myform.on('render', function (f) { myform.form.findField(control_id).on('render', function () { Ext.get(control_id).on('change', function (field, newValue, oldValue) { var obj = Ext.get(control_id).dom; var url = getFullPath(obj); if (img_reg.test(url)) { var newPreview = Ext.get('browser_' + control_id).dom; var showPic = Ext.get("showPic_" + control_id); if (showPic != null) { showPic.remove();//删除原来的图片 } var imgDiv = document.createElement("div"); imgDiv.id = "showPic_" + control_id; document.body.appendChild(imgDiv); imgDiv.style.width = "150px"; imgDiv.style.height = "150px"; imgDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod = scale)"; imgDiv.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = url; newPreview.appendChild(imgDiv); } }, this); }, this); }, this); } //得到图片地址 function getFullPath(obj) { if (obj) { // ie if (window.na vigator.userAgent.indexOf("MSIE") >= 1) { obj.select(); return document.selection.createRange().text; } // firefox else if (window.na vigator.userAgent.indexOf("Firefox") >= 1) { if (obj.files) { return obj.files.item(0).getAsDataURL(); } return obj.value; } return obj.value; } }

这里有几个关键细节值得注意:

  • 正则表达式img_reg用于过滤文件类型,仅允许jpg、jpeg、gif、png、bmp等常见图片格式。
  • 获取文件路径时,IE与其他浏览器需采用不同分支:IE使用document.selection,Firefox(以及Chrome等现代浏览器)应使用getAsDataURL方法。不过当前写法仅兼容Firefox,实际项目中可扩展支持Chrome的FileReader API,此处仅演示核心思路。
  • 预览功能依赖AlphaImageLoader滤镜,该方案仅支持IE浏览器。因此本方法主要解决IE环境下的图片预览问题。对于现代浏览器,直接使用FileReader即可轻松实现,但大量遗留项目仍需兼容IE。

整体实现逻辑清晰:通过change事件捕获用户选择的文件变化,获取本地路径,再借助滤镜将图片投射到div中。预览框的宽高与滤镜的sizingMethod=scale参数配合,图片会自动缩放适配。实际使用时,务必确保FormPanel的fileUpload设置为true,否则上传功能将失败。

来源:https://www.jb51.net/article/29941.htm
上一篇Ext.XTemplate实例代码简单示例 下一篇ExtJS ComboBox加载并赋初值实现方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Vue应用中异步更新性能问题的优化策略详解
前端开发 · 2026-07-03

Vue应用中异步更新性能问题的优化策略详解

先来看一个令许多开发者感到困惑的场景:明明修改了数据,DOM 却“毫无反应”,无法获取最新的高度,也无法计算正确的坐标。这并非 Vue 的缺陷,反而是它精心设计的性能优化策略。核心在于——你需要学会与它“异步更新”的特性协作,而非硬碰硬。 所谓的“异步更新性能问题”,本质上是一种认知偏差。Vue 的

如何避免原型对象挂载大体积动态数组内存污染
前端开发 · 2026-07-03

如何避免原型对象挂载大体积动态数组内存污染

原型链上的大数组:一个隐蔽的内存冲击波 先给个核心判断:直接在原型对象上挂载一个大体积动态数组,这既不是传统意义上的内存“污染”,也不是安全漏洞那种“污染”,而是一种相当隐蔽但后果严重的内存管理失当。它会导致所有实例共享同一份数据,而且正因为生命周期跟整个原型链绑定得太紧,垃圾回收器(GC)根本看不

利用堆栈信息精准定位显式绑定错误对象致未定义异常
前端开发 · 2026-07-03

利用堆栈信息精准定位显式绑定错误对象致未定义异常

深入追踪:显式绑定传错对象引发的未定义异常 说实话,这类问题在JavaScript开发中相当常见——显式绑定传错了对象,然后方法执行时静默失败、访问undefined、或者抛出TypeError。但真正的难点不在于“报了什么错”,而在于“到底是哪个对象被绑错了”。要解决它,需要跳出堆栈的表层报错信息

ES模块中默认导出和具名导出的执行上下文
前端开发 · 2026-07-03

ES模块中默认导出和具名导出的执行上下文

export default 与具名导出在 ES Module 中的行为机制截然不同,核心差异不在于“值如何传递”,而在于绑定如何建立以及导入时如何使用。先给出总结性结论,再逐一详细拆解。 export default 是一种语法糖,而非真正的变量声明 这种设计容易引起误解。实际上,export d

详解HTML中iframe标签loading=lazy属性实现嵌入内容懒加载方法
前端开发 · 2026-07-03

详解HTML中iframe标签loading=lazy属性实现嵌入内容懒加载方法

先聊聊 loading= "lazy " 这个属性——它本意是让 iframe 实现延迟加载,但实际落地时常常“失效”。这并非程序漏洞,而是浏览器内置的防御机制:只有所有条件同时触发,它才会真正推迟资源请求。比如 src 必须是跨域地址(类似 https: widget example com emb