檔案上傳
在不借助第三方的插件的情況下進行檔案上傳可利用:
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:
點選上傳
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
//multiple屬性支援多檔案上傳
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對象,第二個是繪制的起始位置水準,第三個是繪制的垂直位置。