最近在項目中遇到一個比較棘手的問題:在較新版本的瀏覽器(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" on
<input type="button" value="Show Value in FF3" οnclick="alert(getValueFF('foo'))" />
<input type="button" value="Show Value in IE8" οnclick="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>