public/viewjs/ajax.js
function getXhr(){
let xhr=null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
} else {
//为了兼容IE6
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
return xhr;
}
//补充,下方ajax函数参数可用es6语法解构传递参数更方便
function Ajax(obj){ //参数可封装成对象形式的,用着方便,这里就不改了
//用的promise调用的ajax,resolve和reject相信知道promise的都了解
//{resolve,reject,type,headerType, url, headers, data, xhrReturn, progress}
/*
ajax暂停之后不能重新发送请求,需要创建新的xhr对象重新发送请求
*/
let xhr = getXhr();
obj.xhrReturn && obj.xhrReturn(xhr);//将xhr对象返回,用于取消上传
let type = obj.type ? obj.type.toUpperCase() : 'POST';
let url = obj.url ? obj.url : '';
let headerType = obj.headerType?obj.headerType:1;
let headers;
if(headerType == 1){ //前后台正常交互
headers = obj.headers ? obj.headers : {contentType:'application/json'};
}else if(headerType == 2){ //上传文件
headers = obj.headers ? obj.headers : {contentType:'multipart/form-data'};
}
let resolve = obj.resolve ? obj.resolve : function(){};
let reject = obj.reject ? obj.reject : function(){};
let data = obj.data ? obj.data : '';
let reg = new RegExp('\\?',"g");
if(reg.test(url)){
reject("url地址传递错误");
return ;
}
let random = Math.random();
url += "?"+random;
if(type == 'GET'){
reject("不支持GET提交方式");
} else if(type == 'POST'){
xhr.open('POST', url, true);
if(typeof headers == 'object'){
for(let key in headers){
// 如果需要像 html 表单那样 POST 数据,请使用 setRequestHeader() 来添加 http 头。
xhr.setRequestHeader(key, headers[key]);
}
}else{
reject("请求头设置有误");
return ;
}
xhr.withCredentials = false;
obj.progress && (xhr.upload.onprogress = obj.progress);
xhr.onabort = ()=>{
xhr = null;
};
xhr.send(data);
}
// 处理返回数据
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
console.log(xhr.responseText);
let resp = JSON.parse(xhr.responseText);
resolve(resp);
} else {
reject("提交失败,请重试");
}
}
}
}
views/upload.ejs
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title><%= title %>title>
<style>
*{
color:#666666;
}
body,p,div,h1,h2,h3,h4,h5,h6,ul,ol,dl{
margin:0;
padding:0;
}
#upload{
display:none;
}
button{
cursor:pointer;
}
.disabled{
cursor:default;
color:#ccc;
}
.active{
color:#666666;
}
style>
head>
<body>
<input type="file" id="fileInput">
<img id="priview">
<button id="choseBtn">选择文件button>
<button id="uploadBtn" class="disabled">上传button>
<script src="/viewjs/ajax.js">script>
<script>
window.onload = function(){
let fileReader = new FileReader();
let priviewImg = document.getElementById("priview");
let fileInput = document.getElementById("fileInput");
let choseBtn = document.getElementById("choseBtn");
let uploadBtn = document.getElementById("uploadBtn");
let url = 'http://127.0.0.1:3000/file/upload'; //上传地址
choseBtn.onclick = function(){
fileInput.click();
}
fileInput.addEventListener("change",function(e){
let files = e.target.files;
if(files.length <= 0)
uploadBtn.className = 'disabled';
else{
uploadBtn.className = 'active';
fileReader.onload = function(e){
// priviewImg.src = e.target.result //预览图片
}
fileReader.readAsDataURL(files[0]);
}
})
uploadBtn.addEventListener("click",function(e){
let className = e.target.className;
let files = fileInput.files;
if(files.length<=0) return ;
let formData = new FormData();
let file = files[0];
formData.append('file',file);
new Promise((resolve,reject)=>{
Ajax({
url,
data:formData,
resolve,
reject,
headerType:2
})
}).then(function(resp){
console.log(resp);
}).catch(function(error){
console.log(error);
})
})
}
script>
body>
html>
先是在app.js添加个路由
//app.js
var uploadRouter = require('./routes/upload');
app.use('/file', uploadRouter);
开始写路由 router/upload.js
没有multiparty依赖的自行安装一下:
npm install multiparty
//router/upload.js
var express = require('express');
var router = express.Router();
var multiparty = require('multiparty');
var util = require('util');
var fs = require('fs');
router.get('/', function (req, res, next) {
res.render('upload', { title: "上传文件" });
});
router.post('/upload', function (req, res, next) {
let storagePath = __dirname+'/../public/files/'
var form = new multiparty.Form({ uploadDir: storagePath });
form.parse(req, function (err, fields, files) {
if (err) {
console.log('parse error: ' + err);
} else {
let inputFile = files.file[0];
let tmpPath = inputFile.path;
// console.log('filespath=' + uploadedPath);
// console.log('filesTmp: ' + inputFile);
// console.log('Filename: ' + inputFile.originalFilename);
// let finalPath = storagePath + inputFile.originalFilename;
let finalPath = __dirname+'/../public/file/' + inputFile.originalFilename;
//移动并重命名为真实文件名
fs.rename(tmpPath, finalPath, function (err) {
if (err) {
console.log('rename error: ' + err);
} else {
console.log('rename ok');
}
});
}
// res.writeHead(200, { 'content-type': 'application/json;charset=utf-8' });
// res.write('received upload:\n\n');
res.status(200).json({ msg: '上传成功' });
res.end();
// res.end(util.inspect({ fields: fields, files: files }));
})
});
module.exports = router;
自行摸索,希望能跟大家多多交流