码迷,mamicode.com
首页 > Web开发 > 详细

5文件上传与下载

时间:2016-07-13 17:13:03      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

java领域有两个常用的文件上传项目:Common-FileUpload和COS。struts2则在原来的文件上传的项目基础上,进行进一步的封装,从而进一步地简化了文件上传。除此之外,struts2对文件下载支持stream的结果类型,通过借助于struts2提供的文件下载支持,应用可以实现非西欧字符文件名的文件下载,并可以在文件下载前检查用户的权限,从而通过授权控制来控制文件的下载。


文件上传原理
表单元素的enctype属性
大部分时候,无需设置表单元素的enctype属性,我们只设置表单的action属性和method属性,其中action属性指定了表单提交到的URL,而method属性指定是以POST还是GET方式提交请求。
表单的enctype属性指定的是表单数据的编码方式,该属性有如下3个值:
application/x-www-form-urlencoded:这是默认的编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。
multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。
text/plain,这种编码方式当表达的action属性为mailto:URL的形式时比较方便,这种方式主要使用与直接通过表单发送邮件的方式。


1使用Common-FileUpload框架上传文件
这个框架是Apache组织下的jakarta-commons项目组下的一个小项目,该框架可以方便的将multipart/form-data类型请求中的各种表单域解析出来,该项目还依赖于另一个项目:Common-IO
登录以下站点下载commons-fileupload-1.2.1将lib\commons-fileupload-1.2.1.jar复制到WEB应用的WEB-INF\lib目录下。
http://commons.apache.org/fileupload/download_fileupload.cgi


然后再将commons-io-1.3.2.jar也复制到WEB应用的WEB-INF\lib目录下。
//下面是通过Common-FileUpload框架进行文件上传的jsp页面代码:
struts2默认使用Jakarta的Common-FileUpload的文件上传解析器。
struts.multipart.parser=jakarta


文件上传页面
文件上传页面只包含两个表单域:文件标题和文件浏览域。当然为了实现文件上传,应该将这两个表单域所在表单的enctype属性设置为"multipart/form-data"。页面代码如下;
<%@ page language="java" contentType="text/html;Charset=GBK"%>
<html>
<head>
<title>简单文件上传</title>
</head>
<body>
<form action="upload.action" method="post" enctype="multipart/form-data">
文件标题:<input type="text" name="title"/><br/>
选择文件:<input type="file" name="upload"/><br/>
<input value="上传" type="submit"/>
</form>
</body>
</html>


Struts2使用File类型来封装文件域,下面是处理上传请求的Action类代码:
package lee;
import java.io.*;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;


public class uploadAction extends ActionSupport
{
 //封装文件标题请求参数的属性
 private String title;
 //封装上传文件域的属性
     private File upload;
 //封装上传文件类型的属性
     private String uploadContentType;
 //封装上传文件名的属性
    private String uploadFileName;
 //接受依赖注入的属性
     private String savePath;
 //接受依赖注入的方法
     public void setSavePath(String value)
 {
         this.savePath = value;
     }


 //返回上传文件的保存位置
     private String getSavePath() throws Exception 
 {
         return ServletActionContext.getRequest().getRealPath(savePath);
     }


 //文件标题的setter和getter方法
 public void setTitle(String title)
{
  this.title = title; 
 }
 public String getTitle()
{
  return (this.title); 
 }


 //上传文件对应文件内容的setter和getter方法
 public void setUpload(File upload) 
{
  this.upload = upload; 
 }
 public File getUpload() 
{
  return (this.upload); 
 }


 //上传文件的文件类型的setter和getter方法
 public void setUploadContentType(String uploadContentType) 
{
  this.uploadContentType = uploadContentType; 
 }


 public String getUploadContentType()
{
  return (this.uploadContentType); 
 }


 //上传文件的文件名的setter和getter方法
 public void setUploadFileName(String uploadFileName) 
{
  this.uploadFileName = uploadFileName; 
 }


 public String getUploadFileName()
{
  return (this.uploadFileName); 
 }


 @Override
    public String execute() throws Exception
 {
  //以服务器的文件保存地址和原文件名建立上传文件输出流
  FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
  
//以上传文件建立一个文件上传流
  FileInputStream fis = new FileInputStream(getUpload());
  //将上传文件的内容写入服务器
  byte[] buffer = new byte[1024];
  int len = 0;
  while ((len = fis.read(buffer)) > 0)
  {
   fos.write(buffer , 0 , len);
  }
         return SUCCESS;
    }
}


上面的Action与普通的action并没有太大的不同,一样提供了upload和title两个属性,这两个属性分别对应前面的标题和文件域。该Action还包含了两个属性:uploadFileName和uploadContentType这两个属性分别用于封装上传文件的文件名,上传文件的文件类型。因为Action类直接通过File类型属性封装了上传文件的文件内容,但这个File属性无法获取上传文件的文件名和文件类型,所以Struts2直接将文件域包含的上传文件名和文件类型的信息封装到uploadFielName和uploadContentType属性中。可以认为:如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装文件域的信息:
类型为File的xxx属性封装了该文件域对应的文件内容。
类型为String的xxxFileName属性封装了该文件域对应的文件的文件名。
类型为String的xxxContextType属性封装了该文件域对应的文件的文件类型。
上面的Action还包含了一个savePath属性,该属性的值通过配置文件来设置,从而允许的动态设置该属性的值。这也是典型的依赖注入。


配置文件上传的Action与配置普通的Action并没有太大的不同,一个小小的区别是该Action还配置了一个<param../>元素,该元素用于为Action的属性动态分配属性值。如:
<param name="savePath">/upload</param>
该<param.../>元素设置了uploadAction的savePath属性值。将上传的文件保存到web项目的upload目录下。


在web.xml中增加ActionContextCleaUp的配置,这个类也是一个Filter,此处加载该Filter的原因是减少struts2的文件上传引用过程中的未知异常。
<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
<display-name>Struts 2.0 Hello World </display-name> 
<filter> 
<filter-name>struts2</filter-name> 
<filter-class> 
org.apache.struts2.dispatcher.FilterDispatcher 
</filter-class> 
</filter> 
<filter-mapping> 
<filter-name>struts2</filter-name> 
<url-pattern>/* </url-pattern> 
</filter-mapping> 
<!-- 配置Struts2的CleanUp的Filter -->
<filter> 
<filter-name>struts-cleanup</filter-name> 
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class> 
</filter>
<!-- 定义Struts2的CleanUp Filter拦截的URL -->
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list> 
<welcome-file>index.html </welcome-file> 
</welcome-file-list> 
</web-app> 
上面完成一个简单的上传,一次上传一个文件,以被上文件的文件名保存,遇到同名的文件将覆盖掉。


2手动实现文件过滤
为了让上面的Action增加文件过滤的功能,在上面的Action中增加了如下的方法:
/**
*过滤文件类型
*@param types 系统所有允许上传的文件类型
*@return 如果上传文件的文件类型允许上传,返回null,否则返回input字符串。
*/
public String filterType(String[] types){
//取得上传文件的文件类型
String fileType=getUploadContentType();
//遍历
for(String type:types){
if(type.equals(fileType)){
return null;
}
}
return INPUT;
}
filterType方法判断上传文件的文件类型是否在允许上传文件类型列表中,为了让应用程序可以动态配置允许上传文件列表,可以为该Action类增加一个allowTypes属性,该属性的值列出了所有允许上传的文件类型,并在struts.xml的Action中配置相应的<param.../>。在Action类增加的代码如下:
//定该Action允许上传的文件类型
private String allowTypes;
//allowTypes属性的setter和getter方法
public String getAllowTypes(){
return allowTypes;
}
public void setAllowTypes(String allowTypes){
this.allowTypes=allowTypes;
}


<param name="allowTypes">image/bmp,image/png,image/gif,image/jpg</param>
这里的image/bmp,image/png等分别对应于.bmg,.png类型的文件。最下面我们列出了struts2支持的文件类型。


下面在该Actin的execute方法中增加判断,判断上传文件的文件类型是否允许上传。
 @Override
    public String execute() throws Exception
 {
//将允许上传文件类型的字符串以英文逗号分解成字符串数组
//判断当前文件类型是否允许上传
String filterResult=filterType(getAllowTypes().split(","));
//如果当前文件类型不允许上传,如果类型不匹配直接返回INPUT跳出,否则就继续执行上传操作。
if(filterResult != null){
addFieldError("shangchuan","上传文件的类型不正确!");
return filterResult;
}


//以服务器的文件保存地址和原文件名建立上传文件输出流
  FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
//以上传文件建立一个文件上传流
  FileInputStream fis = new FileInputStream(getUpload());
  //将上传文件的内容写入服务器
  byte[] buffer = new byte[1024];
  int len = 0;
  while ((len = fis.read(buffer)) > 0)
  {
   fos.write(buffer , 0 , len);
  }
         return SUCCESS;
    }
}


3拦截器实现文件过滤
struts2还提供了一个文件上传的拦截器,通过配置该拦截器,可以轻松地实现文件过滤,struts2中文件上传的过滤器是fileUpload,为了让该拦截器其作用,只需要在该Action中配置该拦截器引用即可。
配置fileUpload拦截器时,可以为其指定两个参数:
allowTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。
maximumSize:该参数指定允许上传的文件大小,单位是字节。
通过配置fileUpload的拦截器,可以轻松地实现文件过滤,当文件过来失败后,系统自动转入input逻辑视图,因此必须为Action配置名为input的逻辑视图,除此之外,如果使用文件上传拦截器来过滤文件大小,或过滤文件内容则必须显式地为该Action配置引用struts2默认的拦截器栈:defaultStack。
<!--配置fileUpload的拦截器-->
<interceptor-ref name="fileUpload">
<!--配置允许上传的文件类型-->
<param name="allowedTypes">image/bmgp,image/png,image/gif,image/jpeg,image/x-png</param>
<!--配置允许上传的文件大小-->
<param name="maximumSize">2000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>


当使用拦截器实现文件过滤时,如果上传失败,系统返回原来上传页面,没有任何提示。这种方式不够友好。为了在上传页面输出失败提示,需要在页面中增加<s:fielderror/>输出错误提示,但是这个提示是英文的,对于中的Web应用而言,应该使用国际化信息替换它。上传文件太大的提示信息的key是"struts.message.error.file.too.large"如果在自己的国际化资源文件中增加该key的消息,将改变该提示信息。上传文件类型不匹配的提示信息的key是"struts.messages.error.content.type.not.allowed"




4同时上传多个文件
struts2也可以很方便地实现多文件上传,如果页面中有多个文件域需要实现上传则可以为每个文件域提供3个属性,分别封装该文件域对应的文件名,文件类型和文件内容。使用数组和List类处理同时上传多个文件。
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<html>
<title>多文件上传</title>
<body>
<form action="kk/upload.action"  method="post" enctype="multipart/form-data">
文件标题:<input type="text" name="title"/><br/>
文件1:<input type="file" name="upload"/><br/>
文件2:<input type="file" name="upload"/><br/>
文件3:<input type="file" name="upload"/><br/>
<input value="上传" type="submit"/>
</form>
</body>
</html>
上面的三个文件有相同的name属性,因此只需要使用一个数组属性就可以封装该文件域。当然,实际上需要三个数组分别封装文件名,文件类型,和文件内容。如下:
package  action;
import java.io.*;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;


public class uploadAction extends ActionSupport
{
 //封装文件标题请求参数的属性
 private String title;
 //封装上传文件域的属性
     private File[] upload;
 //封装上传文件类型的属性
     private String[] uploadContentType;
 //封装上传文件名的属性
    private String[] uploadFileName;
 //接受依赖注入的属性
     private String savePath;
 //接受依赖注入的方法
     public void setSavePath(String value)
 {
         this.savePath = value;
     }


 //返回上传文件的保存位置
     private String getSavePath() throws Exception 
 {
    System.out.println("**************"+savePath);
         return ServletActionContext.getRequest().getRealPath(savePath);
     }


 //文件标题的setter和getter方法
 public void setTitle(String title)
{
  this.title = title; 
 }
 public String getTitle()
{
  return (this.title); 
 }


 //上传文件对应文件内容的setter和getter方法
 public void setUpload(File[] upload) 
{
  this.upload = upload; 
 }
 public File[] getUpload() 
{
  return (this.upload); 
 }


 //上传文件的文件类型的setter和getter方法
 public void setUploadContentType(String[] uploadContentType) 
{
  this.uploadContentType = uploadContentType; 
 }


 public String[] getUploadContentType()
{
  return (this.uploadContentType); 
 }


 //上传文件的文件名的setter和getter方法
 public void setUploadFileName(String[] uploadFileName) 
{
  this.uploadFileName = uploadFileName; 
 }


 public String[] getUploadFileName()
{
  return (this.uploadFileName); 
 }


 //上传文件函数:
 public String uploadfile() throws Exception
 {
//取得需要上传的文件数组
File[] files=getUpload();
//遍历每个需要上传的文件
for(int i=0;i<files.length;i++){
  //以服务器的文件保存地址和原文件名建立上传文件输出流
  FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName()[i]);
  
//以上传文件建立一个文件上传流
  FileInputStream fis = new FileInputStream(files[i]);
  //将上传文件的内容写入服务器
  byte[] buffer = new byte[1024];
  int len = 0;
  while ((len = fis.read(buffer)) > 0)
  {
   fos.write(buffer , 0 , len);
  }
}
         return SUCCESS;
    }
 
}
上面是使用数组完成多个文件上传,也可以使用List来上传,方式基本一样,只是将数组换成List而已。它与单个文件上传并没有复杂多少。


5使用Struts2控制文件下载
可能很多人会觉得,文件下载太简单,直接在页面上给出一个超级链接,该链接的href属性等于要下载文件的文件名,不就可以实现文件下载了吗?大部分时候的确可以实现文件下载,但如果该文件的文件名为中文文件名,则会导致下载失败;或者应用程序需要在让用户下载之前进行进一步检查,比如判断用户是否有足够权限来下载该文件等。
看下面的一个原始的下载页面代码片段:
<h1>原始的下载</h1>
<ul><li>
<!-- 包含中文文件名的下载链接 -->
下载Struts2的Logo:<a href="images/中.gif">下载图形文件</a>
</li><li>
下载Struts2的Logo的压缩文件:<a href="images/struts-gif.zip">下载压缩文件</a>
</li></ul>
上面页面的包含两个下载的超级链接,两个链接的资源都是存在的,但因为第一个资源文件的文件名是中文文件名,如果单击第一个超级链接,将出现如下图所示的页面。
从图中页面中椭圆形框包围的地方,我们看到被下载的文件名变成了包含大量%的字符串,很明显,这种文件名显然无法取得需要下载的文件。
为了解决这个问题,我们使用Struts2的文件下载支持来下载该文件。


实现文件下载的Action
Struts2的文件下载Action与普通的Action并没有太大的不同,仅仅是该Action需要提供一个返回InputStream流的方法,该输入流代表了被下载文件的入口。该Action类的代码如下:
public class FileDownloadAction implements Action
{
//该属性是依赖注入的属性,该属性可以在配置文件中动态指定该属性值
private String inputPath;
//依赖注入该属性值的setter方法
public void setInputPath(String value)
{
inputPath = value;
}
/*
下载用的Action应该返回一个InputStream实例,
该方法对应在result里的inputName属性值为targetFile
*/
public InputStream getTargetFile() throws Exception
{
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
//处理用户请求的execute方法,该方法返回success字符串
public String execute() throws Exception
{
return SUCCESS;
}
}
从上面的Action中看到,该Action中包含了一个getTargetFile()方法,该方法返回一个InputStream输入流,这个输入流返回的是下载目标文件的入口。该方法的方法名为getTargetFile,表明该Action有一个targetFile属性来返回下载文件。
一旦我们定义了该Action,就可通过该Action来实现文件下载。


配置Action
配置该文件下载的Action与配置普通的Action并没有太大的不同,需要在配置普通Action的基础之上,在加上额外的download的拦截器引用。
除此之外,关键是需要配置一个类型为stream的结果,配置stream类型的结果时需要指定如下四个属性:
 contentType:指定被下载文件的文件类型。
 inputName:指定被下载文件的入口输入流。
 contentDisposition:指定下载的文件名。
 bufferSize:指定下载文件时的缓冲大小。
因为stream结果类型的逻辑视图是返回给客户端一个输入流,因此无需指定location属性。
提示:配置stream类型的结果时,因为无需指定实际的显示的物理资源,所以无需指定location属性,只需要指定inputName属性,该属性指向被下载文件。
下面是配置该下载所用的Action类的配置文件片段:
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Struts2配置文件的DTD信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 配置Struts2国际化资源文件的baseName -->
<constant name="struts.custom.i18n.resources" value="globalMessages"/>
<!-- 配置Struts2应用的编码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置下载的拦截器引用 -->
<default-action-ref name="download"/>
<action name="download" class="lee.FileDownloadAction">
<!-- 指定被下载资源的位置 -->
<param name="inputPath">\images\中.gif</param>
<!-- 配置结果类型为stream的结果 -->
<result name="success" type="stream">
<!-- 指定下载文件的文件类型 -->
<param name="contentType">image/gif</param>
<!-- 指定下载文件的文件位置 -->
<param name="inputName">targetFile</param>
<param name="contentDisposition">filename="struts.gif"</param>
<!-- 指定下载文件的缓冲大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
</struts> 
















**************************
使用jakarta_Commons_FileUpload


从V1.1版开始,FileUpload就开始支持servlet和porlet的文件上传请求,我们将在servlet环境里实现文件上传。
为了确保是一个文件上传请求,FileUpload是通过调用一个静态的方法来判断:
boolean isMultipart=ServletFileUpload.isMultipartContent(request);


上传项目只要足够小,就应该保留在内存里。
较大的项目应该被写在硬盘的临时文件上。
限制项目在内存中所占的控件,限制最大的上传请求,并设置临时文件的位置。
处理上面的情况很简单:
//创建一个工厂函数:
DiskFileItemFactory factory=new DiskFileItemFactory();
//设置工厂函数常量
factory.setSizeThreshold(yourMaxMemotySize);//上传所用的最大内存大小
factory1.setRepository(yourTempDirectory);//设置临时文件保存路径


//创建一个文件上传处理
ServletFileUpload upload = new ServletFileUpload(factory);
//设置最大上传文件
upload.setSizeMax(1024*1024*20);


//转换request
List<FileItem> items = upload.parseRequest(request);


上面的语句执行完,你会得到一个待处理的文件项目列表。你可以这样来处理文件上传域和正常的表单域:
Iterator iter=items.iterator();
while(iter.hasNext()){
FileItem item=(FileItem)iter.next();
//对于普通的表单域
if(item.isFormField()){
String name=item.getFieldName();//获得普通表单域的名称
String value=item.getString();//获得普通表单域的值
....
}


//对于文件上传域
if(!item.isFormField()){
String fieldName=item.getFieldName();//获得文件域的名称
String fileName=item.getName();//获得文件名
String contentType=item.getContentType();//获得文件类型
long sizeInBytes=item.getSize();//获得上传文件的大小


//以当前时间来生成上传文件的文件名
FileOutputStream fos=new FileOutputStream(request.getRealPath("/")+System.currentTimeMillis()+fileName.substring(fileName.lastIndexOf("."),fileName.length()));




//如果上传文件域对应文件的内容已经在内容中
if(item.isInMemory()){
//用get()方法来获得数据的二进制数据形式
fos.write(item.get());
}
//如果文件内容不完全在内存中
else{
//获取上传文件内容的输入流
InputStream is=item.getInputStream();
byte[] buffer=new byte[1024];
int len;
//读取上传文件的内容,并将其写入服务器的文件中
while((len=is.read(buffer))>0){
fos.write(buffer,0,len);
}
is.close();
fos.close();
}


....
}
}
注意因为使用的enctype="multipart/form-data"提交表单,在后台想获取普通表单元素(如文本域)的内容不能使用reqest.getParameter("name")形式获得,这样获取会报错。应该向上面那样先判断是否是普通文本域,在进行处理。


监听进度:
ProgressListener progessListener=new ProgressListener(){
private long megaBytes=-1;
public void update(long pBytesRead,long pContentLength,int pItems){
long mBytes=pBytesRead/1000000;
if(megaBytes==mBytes){
return;
}
megaBytes=mBytes;
System.out.println("We area currently reading item"+pItems);
if(pContentLength==-1){

System.out.println("So far,"+ pBytesRead+"bytes have been read.");
}else{
System.out.println("So far,"+pBytesRead+"of "+ pContentLength+ "bytes have been read.");
}
}
};










**********************************
注意采用struts2上传框架应该配置struts.multipart.maxSize这个常量的值,如果不配置struts2会给它一个默认值,这样如果上传大一些的文件比如6M,就不会被上传:
<constant name="struts.multipart.maxSize" value="1073741824"/>




*************************************
struts2支持的文件类型:
‘.a‘      : ‘application/octet-stream‘, 
‘.ai‘     : ‘application/postscript‘, 
‘.aif‘    : ‘audio/x-aiff‘, 
‘.aifc‘   : ‘audio/x-aiff‘, 
‘.aiff‘   : ‘audio/x-aiff‘, 
‘.au‘     : ‘audio/basic‘, 
‘.avi‘    : ‘video/x-msvideo‘, 
‘.bat‘    : ‘text/plain‘, 
‘.bcpio‘ : ‘application/x-bcpio‘, 
‘.bin‘    : ‘application/octet-stream‘, 
‘.bmp‘    : ‘image/x-ms-bmp‘, 
‘.c‘      : ‘text/plain‘, 
# Duplicates :( 
‘.cdf‘    : ‘application/x-cdf‘, 
‘.cdf‘    : ‘application/x-netcdf‘, 
‘.cpio‘   : ‘application/x-cpio‘, 
‘.csh‘    : ‘application/x-csh‘, 
‘.css‘    : ‘text/css‘, 
‘.dll‘    : ‘application/octet-stream‘, 
‘.doc‘    : ‘application/msword‘, 
‘.dot‘    : ‘application/msword‘, 
‘.dvi‘    : ‘application/x-dvi‘, 
‘.eml‘    : ‘message/rfc822‘, 
‘.eps‘    : ‘application/postscript‘, 
‘.etx‘    : ‘text/x-setext‘, 
‘.exe‘    : ‘application/octet-stream‘, 
‘.gif‘    : ‘image/gif‘, 
‘.gtar‘   : ‘application/x-gtar‘, 
‘.h‘      : ‘text/plain‘, 
‘.hdf‘    : ‘application/x-hdf‘, 
‘.htm‘    : ‘text/html‘, 
‘.html‘   : ‘text/html‘, 
‘.ief‘    : ‘image/ief‘, 
‘.jpe‘    : ‘image/jpeg‘, 
‘.jpeg‘   : ‘image/jpeg‘, 
‘.jpg‘    : ‘image/jpeg‘, 
‘.js‘     : ‘application/x-javascript‘, 
‘.ksh‘    : ‘text/plain‘, 
‘.latex‘ : ‘application/x-latex‘, 
‘.m1v‘    : ‘video/mpeg‘, 
‘.man‘    : ‘application/x-troff-man‘, 
‘.me‘     : ‘application/x-troff-me‘, 
‘.mht‘    : ‘message/rfc822‘, 
‘.mhtml‘ : ‘message/rfc822‘, 
‘.mif‘    : ‘application/x-mif‘, 
‘.mov‘    : ‘video/quicktime‘, 
‘.movie‘ : ‘video/x-sgi-movie‘, 
‘.mp2‘    : ‘audio/mpeg‘, 
‘.mp3‘    : ‘audio/mpeg‘, 
‘.mpa‘    : ‘video/mpeg‘, 
‘.mpe‘    : ‘video/mpeg‘, 
‘.mpeg‘   : ‘video/mpeg‘, 
‘.mpg‘    : ‘video/mpeg‘, 
‘.ms‘     : ‘application/x-troff-ms‘, 
‘.nc‘     : ‘application/x-netcdf‘, 
‘.nws‘    : ‘message/rfc822‘, 
‘.o‘      : ‘application/octet-stream‘, 
‘.obj‘    : ‘application/octet-stream‘, 
‘.oda‘    : ‘application/oda‘, 
‘.p12‘    : ‘application/x-pkcs12‘, 
‘.p7c‘    : ‘application/pkcs7-mime‘, 
‘.pbm‘    : ‘image/x-portable-bitmap‘, 
‘.pdf‘    : ‘application/pdf‘, 
‘.pfx‘    : ‘application/x-pkcs12‘, 
‘.pgm‘    : ‘image/x-portable-graymap‘, 
‘.pl‘     : ‘text/plain‘, 
‘.png‘    : ‘image/png‘, 
‘.pnm‘    : ‘image/x-portable-anymap‘, 
‘.pot‘    : ‘application/vnd.ms-powerpoint‘, 
‘.ppa‘    : ‘application/vnd.ms-powerpoint‘, 
‘.ppm‘    : ‘image/x-portable-pixmap‘, 
‘.pps‘    : ‘application/vnd.ms-powerpoint‘, 
‘.ppt‘    : ‘application/vnd.ms-powerpoint‘, 
‘.ps‘     : ‘application/postscript‘, 
‘.pwz‘    : ‘application/vnd.ms-powerpoint‘, 
‘.py‘     : ‘text/x-python‘, 
‘.pyc‘    : ‘application/x-python-code‘, 
‘.pyo‘    : ‘application/x-python-code‘, 
‘.qt‘     : ‘video/quicktime‘, 
‘.ra‘     : ‘audio/x-pn-realaudio‘, 
‘.ram‘    : ‘application/x-pn-realaudio‘, 
‘.ras‘    : ‘image/x-cmu-raster‘, 
‘.rdf‘    : ‘application/xml‘, 
‘.rgb‘    : ‘image/x-rgb‘, 
‘.roff‘   : ‘application/x-troff‘, 
‘.rtx‘    : ‘text/richtext‘, 
‘.sgm‘    : ‘text/x-sgml‘, 
‘.sgml‘   : ‘text/x-sgml‘, 
‘.sh‘     : ‘application/x-sh‘, 
‘.shar‘   : ‘application/x-shar‘, 
‘.snd‘    : ‘audio/basic‘, 
‘.so‘     : ‘application/octet-stream‘, 
‘.src‘    : ‘application/x-wais-source‘, 
‘.sv4cpio‘: ‘application/x-sv4cpio‘, 
‘.sv4crc‘ : ‘application/x-sv4crc‘, 
‘.swf‘    : ‘application/x-shockwave-flash‘, 
‘.t‘      : ‘application/x-troff‘, 
‘.tar‘    : ‘application/x-tar‘, 
‘.tcl‘    : ‘application/x-tcl‘, 


‘.tex‘    : ‘application/x-tex‘, 
‘.texi‘   : ‘application/x-texinfo‘, 
‘.texinfo‘: ‘application/x-texinfo‘, 
‘.tif‘    : ‘image/tiff‘, 
‘.tiff‘   : ‘image/tiff‘, 
‘.tr‘     : ‘application/x-troff‘, 
‘.tsv‘    : ‘text/tab-separated-values‘, 
‘.txt‘    : ‘text/plain‘, 
‘.ustar‘ : ‘application/x-ustar‘, 
‘.vcf‘    : ‘text/x-vcard‘, 
‘.wav‘    : ‘audio/x-wav‘, 
‘.wiz‘    : ‘application/msword‘, 
‘.wsdl‘   : ‘application/xml‘, 
‘.xbm‘    : ‘image/x-xbitmap‘, 
‘.xlb‘    : ‘application/vnd.ms-excel‘, 
‘.xls‘    : ‘application/excel‘, 
‘.xls‘    : ‘application/vnd.ms-excel‘, 
‘.xml‘    : ‘text/xml‘, 
‘.xpdl‘   : ‘application/xml‘, 
‘.xpm‘    : ‘image/x-xpixmap‘, 
‘.xsl‘    : ‘application/xml‘, 
‘.xwd‘    : ‘image/x-xwindowdump‘, 
‘.zip‘    : ‘application/zip‘, 
firefox 和 ie 的文件类型区别
firefox image/jpeg image/bmp image/gif image/png   


ie 6 image/pjpeg image/bmp image/gif image/x-png   


ie 7 image/pjpeg image/bmp image/gif image/x-png   


ie 8 image/pjpeg image/bmp image/gif image/x-png 















5文件上传与下载

标签:

原文地址:http://blog.csdn.net/bin71722/article/details/51889642

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!