多系统,多种浏览器下:文件上下载的文件名和路径问题
当通过HTML实现上载文件时,通常使用组件<input type="file" name='filename' size="100">,一般通过Windows的浏览器访问时,都会复制一个全路径的文件名,这时,就需要通过JavaScript解析,将文件名取出来,函数可能如下:
function getFileName(input)
{
var tmpstr=""+input;
var pos = tmpstr.lastIndexOf("/");
if(pos == -1){
pos = tmpstr.lastIndexOf("\\");
}
var filename = tmpstr.substr(pos +1)
return filename;
}
表面上看起来,Perfect! 是的,它确实没啥问题。
但是,如果通过MAC系统下访问这个web系统,结果会如何呢? 而且,在MAC系统下,文件名是可以含有 \ 或者 / 的。
或许你已经猜到了,先用一个文件作为例子吧。 测试的文件的HTML内容如下:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="199">
<title>Upload File</title>
<script language="javascript">
function getFileName(input){
alert(input);
var tmpstr=""+input;
var pos = tmpstr.lastIndexOf("/");
if(pos == -1){
pos = tmpstr.lastIndexOf("\\");
}
var filename = tmpstr.substr(pos +1)
return filename;
}
function SaveFile(form, filenum){
var filename = getFileName(form.filename.value);
alert(input);
return true;
}
</script>
</head>
<body>
<form name="uploadfile" method="post" action="upload" enctype="multipart/form-data">
<input type="file" name='filename' size="80">
<input type="button" name="Submit" value='Upload' onClick="SaveFile(this.form)">
</form>
</body>
</html>
例如:文件名是 a\test.jpg,通过 getFileName之后,文件名会变成 test.jpg,也就是说,在MAC系统下,也可以work,但是,文件名会被改变,这违背了MAC系统用户的初衷。于是,笔者调查了一下在各个系统各个主要浏览器的对于文件上载的feature的特征如下:
在Windows环境下:
IE 8.0 会使用真正的文件的全路径,例如文件test.jpg在C盘根目录下,那么,取得的input的控件的值就是 C:\test.jpg.
Chrome 22.0.1229.92 m 会使用一个假的路径,例如文件test.jpg在C盘根目录下,那么,取得的input的控件的值就是 C:\fakepath\test.jpg.
FireFox 15.0 使用真正的文件名,不含路径
在MAC环境下:
Safari 会使用真正的文件的全路径,例如文件test.jpg在在桌面上,那么,取得的input的控件的值就是 C:\fakepath\test.jpg .
Chrome 20.0.1132.47 m 会使用一个假的路径,例如文件test.jpg在在桌面上,那么,取得的input的控件的值就是 C:\fakepath\test.jpg.
FireFox 15.0 使用真正的文件名,不含路径
在Linux系统环境下: 目前由于没有Linux机器,尚未能得出结果,欢迎有LInux系统和浏览器这提供祥光信息。
Chrome
FireFox 15.0
综上所述,如果需要很好的处理文件上下载,需要根据浏览器和操作系统的这些特性,针对特殊的操作系统处理作出相应的判读和处理。例如:可以根据操作系统的类型针对以上的函数进行修改如下:
function getFileName(input){
var tmpstr=""+input;
alert(input);
if (navigator.platform =="Win32")
{
var pos = tmpstr.lastIndexOf("/");
if(pos == -1){
pos = tmpstr.lastIndexOf("\\");
}
var filename = tmpstr.substr(pos +1)
return filename;
}
else
{
return input;
}
}
当然,这只是在前台的处理方法;在后台,最好的方法就是,用户上传的文件名只用于显示,可以将之存储到DB中,在系统内部再为这个文件创建一个唯一的文件名,用于在文件系统上创建文件。这样就不需要考虑用户到底输入的是什么特殊符号的文件名,都可以正常处理。