欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Ajax異步文件上傳與NodeJS express服務(wù)端處理

 更新時(shí)間:2017年04月01日 11:04:58   作者:去門(mén)口罰站  
本文主要介紹了Ajax異步文件上傳與NodeJS express服務(wù)端處理的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧

為了避免在實(shí)現(xiàn)簡(jiǎn)單的異步文件上傳功能時(shí)候引入一個(gè)第三方庫(kù)文件的尷尬情形(庫(kù)文件可能造成多余的開(kāi)銷(xiāo),拉低應(yīng)用加載速度,尤其是在引入庫(kù)文件之后僅使用其中一兩個(gè)功能的情況下,性?xún)r(jià)比極低),最近了解了一下文件異步上傳的實(shí)現(xiàn)原理,順帶看了看進(jìn)度條、圖片預(yù)覽等功能的實(shí)現(xiàn),做一點(diǎn)簡(jiǎn)單的整理。

文件上傳

HTML結(jié)構(gòu)如下,一個(gè)file input和一個(gè)button。當(dāng)點(diǎn)擊“上傳”按鈕的時(shí)候,將file input選中的文件上傳到服務(wù)器。

<input type="file" name="file" id="file" />
<button id="upload">上傳</button>

以下是“上傳”按鈕的點(diǎn)擊事件處理器,點(diǎn)擊按鈕之后通過(guò)一個(gè)XMLHttpRequest對(duì)象來(lái)實(shí)現(xiàn)發(fā)送異步請(qǐng)求。上傳的內(nèi)容為文件,因此還需要用到FormData對(duì)象,F(xiàn)ormData可以js里面創(chuàng)建表單對(duì)象,將file input的文件append到FormData對(duì)象中,最后調(diào)用XHR對(duì)象的send()方法將表單數(shù)據(jù)發(fā)送出去即可。

var file = document.querySelector('#file');
var upload = document.querySelector('#upload');
var xhr = new XMLHttpRequest();

// 點(diǎn)擊上傳
function uploadFile(event) {
 var formData = new FormData();
 formData.append('test-upload', file.files[0]);
 xhr.onload = uploadSuccess;
 xhr.open('post', '/upload', true);
 xhr.send(formData);
}
// 成功上傳
function uploadSuccess(event) {
 if (xhr.readyState === 4) {
 console.log(xhr.responseText);
 }
}

上傳進(jìn)度

在進(jìn)行文件上傳的時(shí)候,xhr對(duì)象會(huì)有一個(gè)upload屬性,會(huì)提供一個(gè)progress事件,在相應(yīng)的事件處理器里面通過(guò)事件對(duì)象可以知道當(dāng)前的上傳進(jìn)度,利用這個(gè)特點(diǎn)可以很方便地實(shí)現(xiàn)進(jìn)度條或者進(jìn)度提示。

<input type="file" name="file" id="file" />
<button id="upload">上傳</button>
<span id="progress">0%</span>
var progress = document.querySelector('#progress');

// 點(diǎn)擊上傳
function uploadFile(event) {
 var formData = new FormData();
 formData.append('test-upload', file.files[0]);
 xhr.onload = uploadSuccess;
 xhr.upload.onprogress = setProgress;
 xhr.open('post', '/upload', true);
 xhr.send(formData);
}
// 進(jìn)度條
function setProgress(event) {
 if (event.lengthComputable) {
 var complete = Number.parseInt(event.loaded / event.total * 100);
 progress.innerHTML = complete + '%';
 }
}

圖片預(yù)覽

上傳圖片的時(shí)候可以利用FileReader對(duì)象來(lái)實(shí)現(xiàn)圖片預(yù)覽。FileReader可以異步讀取用戶(hù)電腦上的文件,將file input選中的文件傳給FileReader,讀取之后取得文件的URL并設(shè)置為image元素的src即可讓選中的圖片文件顯示出來(lái)。

<input type="file" name="file" id="file" />
<button id="upload">上傳</button>
<span id="progress">0</span>
<img id="image" src="" width="200" />
var file = document.querySelector('#file');
file.addEventListener('change', previewImage, false);
// 圖片預(yù)覽
function previewImage(event) {
 var reader = new FileReader();
 reader.onload = function (event) {
 image.src = event.target.result;
 };
 reader.readAsDataURL(event.target.files[0]);
}

服務(wù)端處理

使用express搭建一個(gè)簡(jiǎn)單的NodeJS服務(wù)端,提供上傳文件的接口。express要支持文件上傳需要用到中間件,在express官網(wǎng)上有很多介紹。這里我使用的是multer中間件,下面是簡(jiǎn)單的使用示例。upload.single表示這個(gè)接口接受的上傳文件數(shù)量為1個(gè),'test-upload'限制了上傳的表單數(shù)據(jù)的鍵為'test-upload'(formData.append(‘test-upload', file.files[0]);)。經(jīng)過(guò)這個(gè)中間件處理之后,通過(guò)req.file可以訪(fǎng)問(wèn)到文件的相關(guān)信息,上傳的文件存放在uploads文件夾中。

const upload = require('multer')({ dest: 'uploads/' });
app.post('/upload', upload.single('test-upload'), (req, res) => {
 // 沒(méi)有附帶文件
 if (!req.file) {
 res.json({ ok: false });
 return;
 }
 // 輸出文件信息
 console.log('====================================================');
 console.log('fieldname: ' + req.file.fieldname);
 console.log('originalname: ' + req.file.originalname);
 console.log('encoding: ' + req.file.encoding);
 console.log('mimetype: ' + req.file.mimetype);
 console.log('size: ' + (req.file.size / 1024).toFixed(2) + 'KB');
 console.log('destination: ' + req.file.destination);
 console.log('filename: ' + req.file.filename);
 console.log('path: ' + req.file.path);
});

由輸出可以看到,文件的命名使用一個(gè)哈希值表示,并且去除了后綴名,想要保持文件的原有的命名格式,需要再通過(guò)fs對(duì)文件進(jìn)行改名。

app.post('/upload', upload.single('test-upload'), (req, res) => {
 // 沒(méi)有附帶文件
 if (!req.file) {
 res.json({ ok: false });
 return;
 }

 // 輸出文件信息
 console.log('====================================================');
 console.log('fieldname: ' + req.file.fieldname);
 console.log('originalname: ' + req.file.originalname);
 console.log('encoding: ' + req.file.encoding);
 console.log('mimetype: ' + req.file.mimetype);
 console.log('size: ' + (req.file.size / 1024).toFixed(2) + 'KB');
 console.log('destination: ' + req.file.destination);
 console.log('filename: ' + req.file.filename);
 console.log('path: ' + req.file.path);
 // 重命名文件
 let oldPath = path.join(__dirname, req.file.path);
 let newPath = path.join(__dirname, 'uploads/' + req.file.originalname);
 fs.rename(oldPath, newPath, (err) => {
 if (err) {
  res.json({ ok: false });
  console.log(err);
 } else {
  res.json({ ok: true });
 }
 });
});

完整代碼

ajax異步文件上傳、進(jìn)度顯示、圖片預(yù)覽

<input type="file" name="file" id="file" />
<button id="upload">上傳</button>
<span id="progress">0</span>
<img id="image" src="" width="200" />
(function () {
 'use strict';

 var file = document.querySelector('#file');
 var upload = document.querySelector('#upload');
 var progress = document.querySelector('#progress');
 var image = document.querySelector('#image');
 var xhr = new XMLHttpRequest();

 upload.addEventListener('click', uploadFile, false);
 file.addEventListener('change', previewImage, false);

 // 點(diǎn)擊上傳
 function uploadFile(event) {
 var formData = new FormData();
 formData.append('test-upload', file.files[0]);
 xhr.onload = uploadSuccess;
 xhr.upload.onprogress = setProgress;
 xhr.open('post', '/upload', true);
 xhr.send(formData);
 }

 // 成功上傳
 function uploadSuccess(event) {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText);
 }
 }

 // 進(jìn)度條
 function setProgress(event) {
 if (event.lengthComputable) {
  var complete = Number.parseInt(event.loaded / event.total * 100);
  progress.innerHTML = complete + '%';
 }
 }

 // 圖片預(yù)覽
 function previewImage(event) {
 var reader = new FileReader();
 reader.onload = function (event) {
  image.src = event.target.result;
 };
 reader.readAsDataURL(event.target.files[0]);
 }
})();

express服務(wù)器提供文件上傳接口

const express = require('express');
const upload = require('multer')({ dest: 'uploads/' });
const path = require('path');
const fs = require('fs');
const port = 8080;

let app = express();

app.set('port', port);
// index.html, index.js放在static文件夾中
app.use(express.static(path.join(__dirname, 'static')));

app.get('*', (req, res) => {
 res.redirect('index.html');
});

app.post('/upload', upload.single('test-upload'), (req, res) => {
 // 沒(méi)有附帶文件
 if (!req.file) {
 res.json({ ok: false });
 return;
 }

 // 輸出文件信息
 console.log('====================================================');
 console.log('fieldname: ' + req.file.fieldname);
 console.log('originalname: ' + req.file.originalname);
 console.log('encoding: ' + req.file.encoding);
 console.log('mimetype: ' + req.file.mimetype);
 console.log('size: ' + (req.file.size / 1024).toFixed(2) + 'KB');
 console.log('destination: ' + req.file.destination);
 console.log('filename: ' + req.file.filename);
 console.log('path: ' + req.file.path);

 // 重命名文件
 let oldPath = path.join(__dirname, req.file.path);
 let newPath = path.join(__dirname, 'uploads/' + req.file.originalname);
 fs.rename(oldPath, newPath, (err) => {
 if (err) {
  res.json({ ok: false });
  console.log(err);
 } else {
  res.json({ ok: true });
 }
 });
});
app.listen(port, () => {
 console.log("[Server] localhost:" + port);
});

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

最新評(píng)論