原生JS Ajax上传文件 FileReader预览图片 nodejs文件上传 express+multipart上传文件处理

  1. 封装原生JS的Ajax

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("提交失败,请重试");
            }
        }
    }
    
}
  1. ejs模板上传文件并调用Ajax

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>
  1. nodejs后台处理

先是在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;

自行摸索,希望能跟大家多多交流

你可能感兴趣的:(js,express,nodejs,upload,nodejs,原生JS,javascript,uploadfile)