Js+Node.JS 完成文件上传
Everett35P
8年前
<p>FormDate 对象使用一些键值对来模拟一个完整的表单,然后使用ajax发送这个 FormData 对象,后端便可以拿到表单中上传的文件。</p> <h2>前端处理</h2> <h3>HTML代码</h3> <pre> <code class="language-javascript"><form> <input type="file" id="uploadFile" name="file"> </form></code></pre> <p>如果只想上传图片:</p> <pre> <code class="language-javascript"><input id="uploadFile" type="file" name="file" accept="image/png,image/gif"/></code></pre> <p>可配置属性:</p> <ul> <li>accept:表示可以选择的文件MIME类型,多个MIME类型用英文逗号分开,常用的MIME类型见下表。</li> <li>multiple:是否可以选择多个文件,多个文件时其value值为第一个文件的虚拟路径。</li> </ul> <h3>常用MIME类型</h3> <table> <thead> <tr> <th>后缀名</th> <th>MIME名称</th> </tr> </thead> <tbody> <tr> <td>*.3gpp</td> <td>audio/3gpp, video/3gpp</td> </tr> <tr> <td>*.ac3</td> <td>audio/ac3</td> </tr> <tr> <td>*.asf</td> <td>allpication/vnd.ms-asf</td> </tr> <tr> <td>*.au</td> <td>audio/basic</td> </tr> <tr> <td>*.css</td> <td>text/css</td> </tr> <tr> <td>*.csv</td> <td>text/csv</td> </tr> <tr> <td>*.doc</td> <td>application/msword</td> </tr> <tr> <td>*.dot</td> <td>application/msword</td> </tr> <tr> <td>*.dtd</td> <td>application/xml-dtd</td> </tr> <tr> <td>*.dwg</td> <td>image/vnd.dwg</td> </tr> <tr> <td>*.dxf</td> <td>image/vnd.dxf</td> </tr> <tr> <td>*.gif</td> <td>image/gif</td> </tr> <tr> <td>*.htm</td> <td>text/html</td> </tr> <tr> <td>*.html</td> <td>text/html</td> </tr> <tr> <td>*.jp2</td> <td>image/jp2</td> </tr> <tr> <td>*.jpe</td> <td>image/jpeg</td> </tr> <tr> <td>*.jpeg</td> <td>image/jpeg</td> </tr> <tr> <td>*.jpg</td> <td>image/jpeg</td> </tr> <tr> <td>*.js</td> <td>text/javascript, application/javascript</td> </tr> <tr> <td>*.json</td> <td>application/json</td> </tr> <tr> <td>*.mp2</td> <td>audio/mpeg, video/mpeg</td> </tr> <tr> <td>*.mp3</td> <td>audio/mpeg</td> </tr> <tr> <td>*.mp4</td> <td>audio/mp4, video/mp4</td> </tr> <tr> <td>*.mpeg</td> <td>video/mpeg</td> </tr> <tr> <td>*.mpg</td> <td>video/mpeg</td> </tr> <tr> <td>*.mpp</td> <td>application/vnd.ms-project</td> </tr> <tr> <td>*.ogg</td> <td>application/ogg, audio/ogg</td> </tr> <tr> <td>*.pdf</td> <td>application/pdf</td> </tr> <tr> <td>*.png</td> <td>image/png</td> </tr> <tr> <td>*.pot</td> <td>application/vnd.ms-powerpoint</td> </tr> <tr> <td>*.pps</td> <td>application/vnd.ms-powerpoint</td> </tr> <tr> <td>*.ppt</td> <td>application/vnd.ms-powerpoint</td> </tr> <tr> <td>*.rtf</td> <td>application/rtf, text/rtf</td> </tr> <tr> <td>*.svf</td> <td>image/vnd.svf</td> </tr> <tr> <td>*.tif</td> <td>image/tiff</td> </tr> <tr> <td>*.tiff</td> <td>image/tiff</td> </tr> <tr> <td>*.txt</td> <td>text/plain</td> </tr> <tr> <td>*.wdb</td> <td>application/vnd.ms-works</td> </tr> <tr> <td>*.wps</td> <td>application/vnd.ms-works</td> </tr> <tr> <td>*.xhtml</td> <td>application/xhtml+xml</td> </tr> <tr> <td>*.xlc</td> <td>application/vnd.ms-excel</td> </tr> <tr> <td>*.xlm</td> <td>application/vnd.ms-excel</td> </tr> <tr> <td>*.xls</td> <td>application/vnd.ms-excel</td> </tr> <tr> <td>*.xlt</td> <td>application/vnd.ms-excel</td> </tr> <tr> <td>*.xlw</td> <td>application/vnd.ms-excel</td> </tr> <tr> <td>*.xml</td> <td>text/xml, application/xml</td> </tr> <tr> <td>*.zip</td> <td>aplication/zip</td> </tr> <tr> <td>*.xlsx</td> <td>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</td> </tr> </tbody> </table> <h3>javascript代码</h3> <pre> <code class="language-javascript">$('#uploadFile').on('change',function(e){ var file = this.files[0]; var formData = new FormData(); formData.append('file',file); $.ajax({ url: '/webgl/upload/zip', type: 'post', data: formData, cache: false, contentType: false, processData: false, success: function(res){ // } }) })</code></pre> <p>这里我是在文件被选择上传后就会立即触发 ajax 上传文件事件,而表单中其他字段我没有使用 FormData 对象,所以 <form> 标签没有添加 enctype="multipart/form-data" 属性。</p> <p>注:</p> <ul> <li>processData 设置为 false 。因为 data 值是 FormData 对象,不需要对数据做处理。</li> <li>cache 设置为 false ,上传文件不需要缓存。</li> <li>contentType 设置为 false 。</li> </ul> <h2>nodejs代码</h2> <h3>multer模块</h3> <p>我使用了 multer 模块,初始化 multer 模块配置</p> <pre> <code class="language-javascript">var storageZip = multer.diskStorage({ destination: function(req, file, cb) { cb(null, 'public/uploads/zip') //文件存储路径 }, filename: function(req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + '.zip') //对文件重新命名,防止文件名冲突 } }) var uploadZip = multer({ storage: storageZip });</code></pre> <h3>路由配置</h3> <pre> <code class="language-javascript">app.post('/webgl/upload/zip', uploadZip.single('file'), function(req, res) { res.json(req.file) })</code></pre> <ul> <li>这里 single() 参数名就是使用 FormData.append() 方法添加时的文件名,这里我用的是 file 。</li> <li>上传结束之后,会把 file 对象返回给前端, file 对象会包含文件名等信息。</li> </ul> <p> </p> <p>来自:https://juejin.im/post/58c64f2b0ce463005479f4d3</p> <p> </p>