Node---上传文件

394 阅读2分钟

这两天撸node都是在 express 框架,下面内容都基于这个框架。

服务器上传文件

服务器上传文件随便上网一搜一大把,但是这里也要简单记录一下我的练习。

上传文件需要引入 multer 这个中间键来处理表单数据,因为上传文件是已input标签type='file'来上传的,所以是一种表单数据。

app.js

const express = require('express');
const multer = require('multer');
const app = express();

var Storage = multer.diskStorage({
  destination(req, file, callback) {
    // 上传文件的目录
    callback(null, './file');
  },
  filename(req, file, callback) {
    // 自定义文件名称
    callback(null, file.fieldname + '_' + Date.now() + '_' + file.originalname);
  }
})

// any 可以上传任意文件
var upload = multer({
  storage: Storage
}).any();

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
})

// 上传文件
app.post('/api/Upload', (req, res) => {
  res.writeHead(200,
    {
      'Content-Type':'text/html',
      'Access-Control-Allow-Origin': '*', // 允许跨域访问
      'Access-Control-Allow-Headers': '*', // 允许访问
    }
  );
  
  upload(req, res, function (err) {
    if (err) {
      return res.end("Something went wrong!");
    }
    return res.end("File uploaded sucessfully!.");
  });
})



let sever = app.listen(8080, '127.0.0.1', () => {
  var host = sever.address().address;
  var port = sever.address().port;

  console.log('http://%s%s', host , port);
})

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <title>Upload - Node JS</title>
</head>
<body>
  <form id="frmUploader" enctype="multipart/form-data" action="api/Upload/" method="post">
    <input type="file" name="uploader" multiple />
    <input type="submit" name="submit" id="btnSubmit" value="上传" />
  </form>
</body>
</html>

创建后的目录结构

终端运行: node app.js 上传文件

这个是在服务端页面建立上传功能,如果需要在用户使用则需要把当前链接放到前端 iframe 里:

<iframe src='http://127.0.0.1:8080/'></iframe>

这样就可以做前端使用上传功能

本地上传文件

本地上传文件,服务端代码不变,在前端使用 fetch FormData 处理(以下代码是react上使用例子):

import React from 'react';

class sendFile extends React.Component {
  
  onChange(e) {
    let file = e.target.files[0];
    let formData = new FormData();

    formData.append('uploader', file);

    fetch('http://127.0.0.1:8080/api/Upload', {
      method: 'POST',
      body: formData,
      // headers: {
      //   'Content-Type': 'multipart/form-data'
      // }
    })
  }

  render() {
    return (
    <div>
      <iframe src='http://127.0.0.1:8080/'></iframe>
      <br />
      <form id="frmUploader" encType="multipart/form-data" method="post">
        <input type='file' name='uploader' onChange={this.onChange} ></input>
      </form>
    </div>
    );
  }
}

export default sendFile;

form表单里面的内容基本和服务端一样,关键处理是在 onChange 中把表单内容(file)用FormData转换,直接传递参数,运行后页面如下:

这样就可以不依赖服务端直接在用户端上传文件。

注意坑

上面注释掉的代码 'headers: { Content-Type': 'multipart/form-data } ',使用post请求时必须去掉headers,不然上传代码报错,这个问题卡了我一个下午(参考文章)里面有对这个问题单详细解释。