近日,项目中被测出bug,说google,ie8,firefox上传照片前,不能正常预览照片。 于是,想啊,找啊,得出一些信息,整理归纳如下:
随着各浏览器版本的升级,对用户安全性要求,新的高版本浏览器都阻止读取客户本地路径。据说黑客会通过FireFox的这一安全隐患向服务器上传文件。
1、现况:解决了ie系列、firefox3浏览器的预览问题,
Safari,google,Opera,暂时还没好的解决办法。
2.核心代码(原理参考:http://chenhua-1984.iteye.com/blog/405262):
js部分:
------------------------
$("#uploadFile").change(function(){
var path = $(this).val();
var bgpath = '/jyimges/glzx/bgphoto.jpg';
if ($.trim(path).length <= 0) {
path = bgpath;
}else if(!checkPath(path)){
path = bgpath;
alert("您选择的上传文件格式不符合要求!<br/>请选择JPG、BMP或PNG格式的文件!",'','400px')
}
if($('#previewDiv')[0].filters) {
try{
$('#previewDiv').html('')[0].filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = path;
}catch(e){
$('#uploadText').css('color','#666').html('');
try{
$('#previewDiv')[0].filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = bgpath;
}catch(e1){}
}
}else{
if ($.browser.mozilla){
path= this.files[0].getAsDataURL(); //这是重点。此值是firefox过加密的,也只有由它可以解析
$('#previewDiv').html('<img src="'+path+'" width="100%" height="100%"/>');
}else{
//随着浏览器对安全性要求的提高,暂对其他浏览器,无法处理。
}
}
});
html部分:
-------------------------
<input id="uploadFile" name="uploadFile" type="file" size="25"/>
<div class="userpicBox" id="previewDiv" tyle="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);"></div>
3、firefox获取上传图片本地全路径。(项目暂时没这个,就用了上面说的.getAsDataURL(),放在这儿,作个参考)
//简单方法
function readFileFirefox(fileBrowser) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (e) {
return;
}
var fileName=fileBrowser.value;
return fileName;
}
//完整方法
function readFileFirefox(fileBrowser) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (e) {
//在firefox地址栏输入:about:config, 再打开页面(过滤器)中,添加:signed.applets.codebase_principal_support 。
alert('Unable to access local files due to browser security settings. To overcome this, follow these steps: (1) Enter "about:config" in the URL field; (2) Right click and select New->Boolean; (3) Enter "signed.applets.codebase_principal_support" (without the quotes) as a new preference name; (4) Click OK and try loading the file again.');
return;
}
var fileName=fileBrowser.value;
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try {
// Back slashes for windows
file.initWithPath( fileName.replace(/\//g, "\\\\") );
} catch(e) {
if (e.result!=Components.results.NS_ERROR_FILE_UNRECOGNIZED_PATH) throw e;
alert("File '" + fileName + "' cannot be loaded: relative paths are not allowed. Please provide an absolute path to this file.");
return;
}
if ( file.exists() == false ) {
alert("File '" + fileName + "' not found.");
return;
}
alert(file.path); // I test to get the local file's path.
var is = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance( Components.interfaces.nsIFileInputStream );
try {
is.init( file,0x01, 00004, null);
} catch (e) {
if (e.result!=Components.results.NS_ERROR_FILE_ACCESS_DENIED) throw e;
alert("Unable to access local file '" + fileName + "' because of file permissions. Make sure the file and/or parent directories are readable.");
return;
}
var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance( Components.interfaces.nsIScriptableInputStream );
sis.init( is );
var data = sis.read( sis.available() );
alert("Data from file: " + data); // I test to get the local file's data.
}
4、个人觉得最通用办法,是用ajax上传图片来预览。只是成本比较高,用户预览了照片,可能会选择放弃上传。这样,就还需要去删除之前的照片。成本太高,除非真的很变态,必需要预览。呵。
2011-2-24总结