文件上传
在不借助第三方的插件的情况下进行文件上传可利用:
Form表单
FormData对象
Form表单是不存在浏览器的兼容性的,同时在js被禁用的情况下也能进行文件的传输,因此可以大胆使用。Form表单提交不同于Ajax,Ajax提交数据还需要利用脚本进行数据的处理,而Form是不需要进行任何数据处理的。
使用Form表单提交文件一个非常典型的应用场景就是上传图片,但是页面不刷新。
常用属性
target(数据提交完后,后台返回数据展示的位置,常用
_blank
,_self
,指定的iframe
)action(数据提交的接口)
enctype(设置上传数据编码类型,常用的
application/x-www-form-urlencoded
,multipart/form-data
)method(HTTP请求的方式,常用
GET
/POST
)
示例
使用Form表单异步上传图片,获取后台返回的图片路径,页面不发生跳转。
Html:
<form action="/" enctype="multipart/form-data" target="test-ifr" method="post">
<input type="file" name="key">
</form>
<button>点击上传</button>
<div id="container"></div>
js:
(function(window) {
var win = window,
btn = document.getElementsByTagName('button')[0],
container = document.getElementById('container'),
form = document.getElementsByTagName('form')[0];
btn.addEventListener('click', function() {
var ifr = document.createElement('iframe');
ifr.id = 'test-ifr';
ifr.name = 'test-ifr';
//隐藏iframe
ifr.style.display = 'none';
container.appendChild(ifr);
//iframe加载事件,获取到数据以前onload会触发一次,获取到数据后再触发一次,需要添加一个判断
ifr.onload = function () {
//后台尽量传JSON的字符串,这样可以确保一致性,同时可以调用innerHTML来获取DOM里面的内容
var _result = JSON.parse(this.contentDocument.getElementsByTagName('body')[0].innerHTML);
//iframe的body标签里面的内容就是从后台传输过来的数据。例如后台传输过来的是图片的url地址
var _img = new Image();
_img.src = _result.url;
container.appendChild(_img);//显示图片
};
//调用Form表单事件
form.submit();
})
})(window);
server:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(express.static('./'));
app.get('/', function (req, res) {
res.sendFile('index.html');
});
app.post('/', function (req, res) {
setTimeout(function () {
var str = JSON.stringify({url: './imgs/1.png'});
res.send(str);
}, 1000);
});
app.listen(3000, function () {
console.log('The server has start up on port of 3000');
});
如果现在需求变化了,必须要求前端上传图片后需要立马在前端展示出来,而不是通过上传至服务器端,拿到Url后再展示。现在HTML5提供了3种API可以做到。
FileReader
canvas
ceateObjectURL()
FileReader
<input type="file" multiple accept="image/*">
//multiple属性支持多文件上传
<div class="img-container"></div>
var aInput = document.getElementByTagName('input')[0],
imgContainer = document.getElementByClassName('img-container')[0];
aInput.addEventListener('change', function() {
for(var i = 0; i < this.files.length; i++) {
var img = new Image(),
reader = new FileReader(),
url = reader.readAsDataURL(this.files[i]);
imgContainer.appendChild(img);
reader.onload = function(e) {
img.src = e.target.result;
}
}
});
这个API主要是是将Image转化成了base64,这样图片就能在不推送的服务器后才显示。
FileReader兼容性
canvas
canvas是在网页中生成一块画图,然后利用drawImage方法,将图片在画布中重新绘制。
var img = new Image(),
canvas;
img.onload = function () {
canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
console.log(canvas.toDataURL());
document.body.appendChild(canvas);
return canvas;
};
img.src = './images/1.png';
//drawImage即将img画到画布区域内,接收三个参数,第一个是img对象,第二个是绘制的起始位置水平,第三个是绘制的垂直位置。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。