Ajax文件上传全解析(前后端项目搭建,进度条显示等)

最终效果:

image.png
前言

文件上传其实跟上传json对象或者文本差不多,我们需要通过给http的请求头设置对应的Content-type来告诉浏览器我们要上传的类型,常见的就是application/json(处理json对象),text/plain(纯文本)和multipart/form-data(文件上传)

项目搭建
  1. 新建文件夹


    image.png
  2. 初始化npm 项目并下载依赖包
npm init -y
npm i webpack webpack-cli@3 webpack-dev-server html-webpack-plugin formidable

webpack-cli如果不指定版本,有可能跟最新版的webpack不兼容,所以这里指定一下
formidable是用来处理后端接受到的http请求body中的文件数据

  1. 在根目录下新建webpack.config.js作为webpack的配置文件
//webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        port:8080
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'ajax上传文件',
            template: path.resolve(__dirname, 'index.html')
        })
    ],
}

代码很简单,就是等下把我们前端的源码通过webpack-dev-server打包进内存,并启动一个服务,然后把打包后的文件引入指定的index.html模板中

  1. 根目录下新建index.html



    
    
    
    Document


    
    
    


  1. 根目录新建src文件,新建文件index.js
;(function () {
    let oFileInput = document.getElementById('file')
    let oSubmit = document.getElementById('submit')
    let file

    function init() {
        oFileInput.addEventListener("change",function (e) {
            file = this.files[0]
        })

        oSubmit.addEventListener("click",function (e) {
            let xhr = new window.XMLHttpRequest()
            xhr.open("post","http://localhost:3000",true)
            var fd = new FormData()
            fd.append("file",file)
            xhr.upload.onprogress = function(e){
                var value = (e.loaded / e.total * 100).toFixed(1);
                console.log(value)
            }
            xhr.send(fd)
        })
    }

    init()
})()

其中值得说的是FormData,他是一个表单构造函数,通过append方法来增加数据,
跟我们自己写一个html表单来上传文件差不多,只是form是同步的,而且页面会跳转到action,而js实例化显然更自由。
而文件的监听进度利用upload对象的onprogress

  1. 后端服务
const http = require('http')
const formidable = require('formidable')
const fs = require('fs')
const path = require('path')

const app = http.createServer((req, res) => {
    const form = new formidable.IncomingForm()
    form.encoding = 'utf-8'
    form.uploadDir = './upload'
    form.parse(req, function (err, fields, files) {
        if (!files.file) return
        let oldpath = path.join(__dirname, files.file.path)
        let newPath = path.join(__dirname, '/upload', files.file.name)
        fs.rename(oldpath, newPath, function (err) {
            if (err) {
                throw Error('改名失败')
            }else{
                console.log("保存文件:",newPath)
            }
        })
    })
    res.writeHead(200, {
        'Content-Type': 'text/html;charset=utf-8', 'Access-Control-Allow-Origin': '*'
    })
    res.end('

哈哈

') }) app.listen(3000, () => { console.log('running!!') })

首先通过http启动一个node服务,通过formidable解析http请求体中的文件数据,最终形成json对象并注入到回调函数中,其中oldPath和newPath是为了修改文件名,因为默认接受到的文件是没有扩展名的,文件无法识别,所以需要我们手动修改一下,最后设置一下跨域头就可以了。

你可能感兴趣的:(Ajax文件上传全解析(前后端项目搭建,进度条显示等))