但上传文件部分只有底层的XMLHttpRequest
对象发送上传请求,那么怎么通过jQuery
的Ajax
上传呢?
本文将介绍通过jQuery
使用FormData
对象上传文件。
使用<form>
表单初始化FormData
对象方式上传文件
HTML代码
<code class="xml" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; background-color: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102);"><<span class="hljs-title" style="color: rgb(38, 139, 210);">form</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">id</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"uploadForm"</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">enctype</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"multipart/form-data"</span>></span> </code><pre class="hljs xml" name="code" style="margin-top: 0px; margin-bottom: 20px; white-space: pre-wrap; word-wrap: normal; padding: 9.5px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; border-radius: 4px; line-height: 20px; word-break: break-all; border: 1px solid rgba(0, 0, 0, 0.14902); overflow: auto; background: rgb(253, 246, 227);"><code class="xml" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; background-color: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102);"><<span class="hljs-title" style="color: rgb(38, 139, 210);">input</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">id</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"abc"</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">type</span>="text<span class="hljs-value" style="color: rgb(42, 161, 152);">"</span> /></span></code><inputid="file"type="file"name="file"/> <buttonid="upload"type="button">upload </button> </form>
<code class="javascript" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; background-color: transparent;">$.ajax({
url: <span class="hljs-string" style="color: rgb(42, 161, 152);">'/upload'</span>,
type: <span class="hljs-string" style="color: rgb(42, 161, 152);">'POST'</span>,
cache: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>,
data: <span class="hljs-keyword" style="color: rgb(133, 153, 0);">new</span> FormData($(<span class="hljs-string" style="color: rgb(42, 161, 152);">'#uploadForm'</span>)[<span class="hljs-number" style="color: rgb(42, 161, 152);">0</span>]),
processData: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>,
contentType: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
}).done(<span class="hljs-function"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">function</span>(<span class="hljs-params" style="color: rgb(102, 0, 102);">res</span>) </span>{
}).fail(<span class="hljs-function"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">function</span>(<span class="hljs-params" style="color: rgb(102, 0, 102);">res</span>) </span>{});</code>
这里要注意几点:
processData
设置为false
。因为data
值是FormData
对象,不需要对数据做处理。<form>
标签添加enctype="multipart/form-data"
属性。cache
设置为false
,上传文件不需要缓存。contentType
设置为false
。因为是由<form>
表单构造的FormData
对象,且已经声明了属性enctype="multipart/form-data"
,所以这里设置为false。
上传后,服务器端代码需要使用从查询参数名为file
获取文件输入流对象,因为<input>
中声明的是name="file"
。
如果不是用<form>
表单构造FormData
对象又该怎么做呢?
使用FormData
对象添加字段方式上传文件
HTML代码
<code class="xml" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; background-color: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102);"><<span class="hljs-title" style="color: rgb(38, 139, 210);">div</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">id</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"uploadForm"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102);"><<span class="hljs-title" style="color: rgb(38, 139, 210);">input</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">id</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"file"</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">type</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"file"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102);"><<span class="hljs-title" style="color: rgb(38, 139, 210);">button</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">id</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"upload"</span> <span class="hljs-attribute" style="color: rgb(181, 137, 0);">type</span>=<span class="hljs-value" style="color: rgb(42, 161, 152);">"button"</span>></span>upload<span class="hljs-tag" style="color: rgb(0, 102, 102);"></<span class="hljs-title" style="color: rgb(38, 139, 210);">button</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102);"></<span class="hljs-title" style="color: rgb(38, 139, 210);">div</span>></span></code>
这里没有<form>
标签,也没有enctype="multipart/form-data"
属性。
javascript代码
<code class="javascript" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; background-color: transparent;"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">var</span> formData = <span class="hljs-keyword" style="color: rgb(133, 153, 0);">new</span> FormData();
formData.append(<span class="hljs-string" style="color: rgb(42, 161, 152);">'file'</span>, $(<span class="hljs-string" style="color: rgb(42, 161, 152);">'#file'</span>)[<span class="hljs-number" style="color: rgb(42, 161, 152);">0</span>].files[<span class="hljs-number" style="color: rgb(42, 161, 152);">0</span>]);</code>
<code class="javascript" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-radius: 3px; border: none; background-color: transparent;">.append('abc',$("#abc").val());
$.ajax({
url: <span class="hljs-string" style="color: rgb(42, 161, 152);">'/upload'</span>,
type: <span class="hljs-string" style="color: rgb(42, 161, 152);">'POST'</span>,
cache: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>,
data: formData,
processData: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>,
contentType: <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
}).done(<span class="hljs-function"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">function</span>(<span class="hljs-params" style="color: rgb(102, 0, 102);">res</span>) </span>{
}).fail(<span class="hljs-function"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">function</span>(<span class="hljs-params" style="color: rgb(102, 0, 102);">res</span>) </span>{});</code>
这里有几处不一样:
append()
的第二个参数应是文件对象,即$('#file')[0].files[0]
。contentType
也要设置为‘false’。
从代码$('#file')[0].files[0]
中可以看到一个<input type="file">
标签能够上传多个文件,
只需要在<input type="file">
里添加multiple
或multiple="multiple"
属性。
服务器端读文件
从Servlet 3.0
开始,可以通过 request.getPart()
或 request.getPars()
两个接口获取上传的文件。
这里不多说,详细请参考官网教程 Uploading Files with Java Servlet Technology 以及示例 The fileupload Example Application
InputPart.getBodyAsString()可以取得字符串.
InputStream inputStream = inputPart
.getBody(InputStream.class, null);来取得具体的文件流.
// ファイルの読む
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream,
Constant.Charset.SHIFT_JIS));
csvReader = new CSVReader(reader);
// 内容をリストに格納する.
resultList = csvReader.readAll();