🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 使用 FormData 文件上传 \[[不使用 FormData 做文件上传](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files)\]([https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using\_XMLHttpRequest#Submitting\_forms\_and\_uploading\_files](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files)) ### 使用 FormData 封装文件参数 ``` var formData = new FormData(); formData.append('username', 'Groucho'); formData.append('password', 123456); // 数字 123456 会被立即转换成字符串 '123456' // file 类型 input formData.append('userfile', document.getElementById("fileId").files[0]); // 上面步骤的等价于自己定义表单元素,里面有对应 input,再通过表单元素来创建 FormData 对象 // JavaScript 创建文件 /* var content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的内容 var blob = new Blob([content], { type: 'text/xml'}); formData.append("webmasterfile", blob); */ ``` ### 代码实现 需求:文件上传。 * 修改页面: ``` <span id="result"></span> <form id='loginForm'> <input type="text" id="username" name="username" placeholder="用户名"> <input type="text" id="password" name="password" placeholder="密码"> <input type="file" id="foo" name="foo"> <input id="login" type="button" value="登录"> </form> ``` 修改 AJAX 代码 ``` window.onload = function(){ var loginEle = document.querySelector('#login'); loginEle.onclick = function(){ // 使用 FormData 来处理参数数据 var formData = new FormData(document.querySelector('#loginForm')); var ajax = new XMLHttpRequest(); ajax.open('post', '/profile', true); // 发送信息至服务器时内容编码类型,默认为 'multipart/form-data' ajax.onload = function () { // 当 xhr.readyState = 4 执行回调函数 2.0 if(ajax.status == 200 ) { document.getElementById('result').innerText = ajax.responseText; } } ajax.send(formData); } } ``` 编写后台代码 ``` const express = require('express'); const fileUpload = require('express-fileupload'); const path = require('path'); const app = express(); app.use(fileUpload()); app.use(express.urlencoded()); app.use('/static', express.static(path.join(__dirname, 'static'))); app.post('/profile', (req, res) => { console.log(req.files.foo) // foo 是上传表单 file input 名称 console.log(req.body); let f = req.files.foo; f.mv(path.join(__dirname, 'static', 'upload', 'a.png'), function(err) { if(err){ return res.status(500).send(err); } res.send('文件上传成功!'); }); }); app.listen(8888, () => { console.log('running...'); }); ``` 思考: 文件上传时出现同名文件覆盖问题怎么解决, 若上传成功, 把上传图片显示下方 ``` f.name+Date.now() ``` # 文件上传度 ajax.upload.onprogress = function(e){ ``` // console.log("\_\_\_\_\_\_\_\_\_\_\_\_"); // console.log(e); if(e.lengthComputable){ // 这里打印,实际情况在页面显示即可 console.log("上传进度:", Math.floor(e.loaded / e.total \* 100) + "%"); } ``` } # 请求超时 ``` var ajax = new XMLHttpRequest(); ajax.open('GET', 'url', true); ajax.timeout = 2000; // 设置超时时间,单位是毫秒 ajax.onload = function () { // 请求完成。在此进行处理。 }; ajax.ontimeout = function (e) { // XMLHttpRequest 超时。在此做某事。 }; ajax.send(null); ```