架构深渊

慢慢走进程序的深渊……关注领域驱动设计、测试驱动开发、设计模式、企业应用架构模式……积累技术细节,以设计架构为宗。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[转]FF3(FireFox3),IE8上传图片实现图片预览的方法

Posted on 2009-09-03 14:31  chen eric  阅读(791)  评论(0编辑  收藏  举报
FF3(FireFox3),IE8上传图片实现图片预览的方法
c# 技术文档   
2009-06-15 11:51   阅读281   评论0   字号: 大大  中中  小小 最近在项目中遇到一个比较棘手的问题:在较新版本的浏览器(Firefox3、IE8、IE7[IE8模拟])中无法获取file input的完整value,我们先看下测试的结果:

Firefox 
2.x、IE6、IE7:在本地及远端都可以取得完整地址(包括路径及文件名)

Firefox 
3.0:在本地及远端都不能取得完整地址,只能获得文件名

IE8、IE7[IE8模拟]:在本地可以取得完整地址(包括路径及文件名),在远端不能取得完整地址,只能获得文件名 

我们从上面的测试信息中看到在新版本的浏览器中在远端均没有办法获得完整的地址,那有没有办法可以解决这个问题呢,我们往下看。

如何在Firefox3下取得完整路径?

第一步:打开“about:config”页面,查找“signed.applets.codebase_principal_support”属性,将其值设置为true。

第二步:在javascript中采用以下代码进行获取:
function getValueFF(id){
    
var ip = document.getElementById(id);
    
if (ip.files) {
        
//ffx3 - try to have access to full path
        try {
            netscape.security.PrivilegeManager.enablePrivilege( 
'UniversalFileRead' )
        }
        
catch (err) {
            
//need to set signed.applets.codebase_principal_support to true
        }
    };
    
return ip.value;



经过以上步骤,在Firefox3下获取file input的value时,会弹出一个Internet Security的对话框,点击
"Allow"将可以获取完整value。

如何在IE8下取得完整路径?

方法一:使用selection.createRange
function getValueIE8(id){
    
var ip = document.getElementById(id);
    ip.select();
    
return document.selection.createRange().text;



方法二:引用:https:
//bugzilla.mozilla.org/attachment.cgi?id=328849

下面是可以运行的代码,大家可以看下测试的结果:

--------------------------------------------------------------------------------
<!doctype html public "-//w3c//dtd html 4.01//en" "http://www.w3.org/tr/html4/strict.dtd">
            
<html>
            
<head>
            
<title>File Input</title>
            <meta http-equiv="content-type" content="text/html; charset=utf-8">
            
<style>
            body{font
-size:13px;}
            .box{border:1px solid #eee;background:#ffe;padding:10px 30px;margin:10px;}
            dt{font
-weight:bold;}
            dt,img,textarea{margin:8px 
0;}
            em{color:#f00; font
-style:normal;}
            span{color:#
999;}
            .ft{color:#
999;font-size:11px;text-align:right}
            
</style>
            </head>
            <body>
            
<h2>在不同浏览器中获取File Input的value</h2>
            <div class="box">
            
<input type="file" name="foo" id="foo" size="60" />
            <input type="button" value="Show Value" onclick="alert(document.getElementById('foo').value)" />
            <input type="button" value="Show Value in FF3" onclick="alert(getValueFF('foo'))" />
            <input type="button" value="Show Value in IE8" onclick="alert(getValueIE8('foo'))" />
            </div>
            <div class="box">
            
<dl>
            
<dt>Firefox 2.x、IE6、IE7</dt>
            <dd>在本地及远端都可以取得完整地址(包括路径及文件名)</dd>
            </dl>
            <dl>
            
<dt>Firefox 3.0</dt>
            <dd>在本地及远端都<em>不能</em>取得完整地址,只能获得文件名</dd>
            
</dl>
            <dl>
            
<dt>IE8、IE7[IE8模拟]</dt>
            <dd>在本地可以取得完整地址(包括路径及文件名),在远端<em>不能</em>取得完整地址,只能获得文件名</dd>
            
</dl>
            <span>* 本地:localhost</span>
            </div>
            <div class="box">
            
<h3>如何在Firefox3下取得完整路径</h3>
            <p>
            第一步:打开
"about:config"页面,查找"signed.applets.codebase_principal_support"属性,将其值设置为true。
            
</p>
            <p>
            第二步:在javascript中采用以下代码进行获取:
<br />
            <textarea style="width:800px;height:300px;">
            
function getValueFF(id){
            
var ip = document.getElementById(id);
            
if (ip.files) {
            
//ffx3 - try to have access to full path
            try {
            netscape.security.PrivilegeManager.enablePrivilege( 
'UniversalFileRead' )
            }
            
catch (err) {
            
//need to set signed.applets.codebase_principal_support to true
            }
            };
            
return ip.value;
            }
            
</textarea>
            </p>
            <p>
            经过以上步骤,在Firefox3下获取file input的value时,会弹出一个Internet Security的对话框,点击
"Allow"将可以获取完整value。<br />
            <span>资料:<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=143220" target="_blank">https://bugzilla.mozilla.org/show_bug.cgi?id=143220</a></span>
            </p>
            </div>
            <div class="box">
            
<h3>如何在IE8下取得完整路径</h3>
            <p>方法一:使用selection.createRange <br />
            <textarea style="width:800px;height:150px;">
            
function getValueIE8(id){
            
var ip = document.getElementById(id);
            ip.select();
            
return document.selection.createRange().text;
            }
            
</textarea>
            </p>
            <p>方法二:引用:<a href="https://bugzilla.mozilla.org/attachment.cgi?id=328849" target="_blank">https://bugzilla.mozilla.org/attachment.cgi?id=328849</a></p>
            </div>
            <script language="JavaScript">
            
function getValueFF(id){
            
var ip = document.getElementById(id);
            
if (ip.files) {
            
//ffx3 - try to have access to full path
            try {
            netscape.security.PrivilegeManager.enablePrivilege( 
'UniversalFileRead' )
            }
            
catch (err) {
            
//need to set signed.applets.codebase_principal_support to true
            }
            };
            
return ip.value;
            }
            
function getValueIE8(id){
            
var ip = document.getElementById(id);
            ip.select();
            
return document.selection.createRange().text;
            }
            
</script>
            </body>
            </html>

--------------------------------------------------------------------------------
在上面我们看到了出现的问题,原因可能是处於对安全性的考量,新版本的浏览器对访问客户端内容设置了较高的权限。虽然现在有变相的 “解决办法”,但都需要用户在访问页面的时候,额外的进行浏览器的安全设置(允许Javascript脚本访问更多的本地内容),否则单靠Javascript还是无法直接进行访问。这就意味这我没有办法像以前那样去直接调用file input的value来进行图片的预览。

那我们是不是有别的什么办法来进行图片的预览呢?继续往下看。

在新版本的浏览器中有提供nsIDOMFile这样一个接口,它提供了三个方法可以使用,分别是:

DOMString getAsBinary();
DOMString getAsDataURL();
DOMString getAsText(
in DOMString encoding);

详细的资料看这裡:https:
//developer.mozilla.org/en/NsIDOMFile

我们这裡就是要使用getAsDataURL()这个方法,这个方法会返回一个data: URL类型的DOMString,它的内容就是文件经过编码后的数据了。

好,下面让我来看下例子吧:

--------------------------------------------------------------------------------
<!doctype html public "-//w3c//dtd html 4.01//en" "http://www.w3.org/tr/html4/strict.dtd">
            
<html xmlns="http://www.w3.org/1999/xhtml">
            
<head>
            
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>New file input tester.</title>
            </head>
            <body>
            
<input id="myfile" type="file" />
            <br />
            <img src="" alt="Image to be upload." />
            <div id="info"></div>
            <script type="text/javascript">
            
var dFile = document.getElementById('myfile');
            
var dImg = document.getElementsByTagName('img')[0];
            
var dInfo = document.getElementById('info');
            dFile.onchange 
= function(){
            
if(!dFile.value.match(/.jpg|.gif|.png|.bmp/i)){alert('File type must be: .jpg, .gif, .bmp or .png !');return;}
            
if(dFile.files){
            dImg.src 
= dFile.files[0].getAsDataURL();
            }
else if(dFile.value.indexOf('\\'> -1 || dFile.value.indexOf('\/'> -1){
            dImg.src 
= dFile.value;
            }
            }
            
</script>
            </body>
            </html>