Node js:尝试将文件上传到 Web 服务器时出现类型错误

问题描述 投票:0回答:1

我是 Node js 新手,正在尝试创建一个功能来监视目标文件夹并将新保存的文件上传到服务器。这会破坏 uploadFile 函数。我不确定 app.post 中还需要什么。谢谢您的帮助!

上传文件时出错:TypeError [ERR_INVALID_ARG_TYPE]:“cb”参数必须是函数类型。收到未定义 在 MaybeCallback (节点:fs:180:3) 在 Object.readFile (节点:fs:371:14) 在 uploadFile (/Users/.../server.js:99:35) 在 Timeout.uploadFromTarget [as _onTimeout] (/Users/.../server.js:86:5) 在 listOnTimeout (节点:内部/计时器:573:17) 在 process.processTimers (节点:内部/计时器:514:7){ 代码:'ERR_INVALID_ARG_TYPE' }

const http = require('http');
const fs = require('fs');
const fetch = import('node-fetch');
const FormData = require('form-data');
const path = require('path');
const express = require('express');
const formidable = require('formidable');
const port = 80;

const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.static('/upload')); // Serve files from the upload directory

// Directories
const uploadDirectory = './upload/'; // Server upload directory
const targetDirectory = '/Users/.../test_tool_logs'; // Simulated target directory

// User Options
const checkInterval = 2 * 1000; // Check every 2 seconds
const uploadInterval = 5 * 1000; // Upload every 5 seconds
const rename_with_date = false; // Add datetime to file name in uploads folder

if (!fs.existsSync(uploadDirectory)) {
    fs.mkdirSync(uploadDirectory, { recursive: true });
}

if (!fs.existsSync(targetDirectory)) {
    fs.mkdirSync(targetDirectory, { recursive: true });
}

let previousFiles = [];
let changedFiles = [];

// Check for changes in the target directory
function checkForChanges() {
    fs.readdir(targetDirectory, (err, files) => {
        if (err) {
            console.error('Failed to read target directory:', err);
            return;
        }

        let currentFiles = files.map(file => {
            let filePath = path.join(targetDirectory, file);
            let stats = fs.statSync(filePath);
            return { name: file, mtime: stats.mtimeMs };
        });

        // Determine new or updated files
        let updates = currentFiles.filter(file => {
            let prev = previousFiles.find(f => f.name === file.name);
            return !prev || file.mtime > prev.mtime;
        });

        if (updates.length > 0) {
            updates.forEach(file => {
                if (!changedFiles.includes(file.name)) {
                    changedFiles.push(file.name);
                }
            });
            console.log('Detected new or updated files:', updates.map(f => f.name));
        }

        previousFiles = [...currentFiles];
    });
}

// Upload a file from changedFiles
function uploadFromTarget() {
    if (changedFiles.length === 0) {
        console.log('No files to upload.');
        return;
    }

    let fileName = changedFiles.shift();
    let sourcePath = path.join(targetDirectory, fileName);

    if (rename_with_date) {
        // Creates a date string in a "YYYY-MM-DD_HH-MM-SS" format
        const date = new Date();
        const dateString = date.toISOString().replace(/:/g, '-').replace('T', '_').substring(0, 19);
        
        const fileExtension = path.extname(fileName);
        fileName = `${path.basename(fileName, fileExtension)}_${dateString}${fileExtension}`;
    }

    uploadFile(sourcePath, uploadDirectory, fileName)
    
    console.log(`Files waiting to upload: ${changedFiles}`);
}

// Set intervals for checking changes and uploading files
setInterval(checkForChanges, checkInterval);
setInterval(uploadFromTarget, uploadInterval);


async function uploadFile(filePath, uploadUrl, fileName) {
    try {
      // Read file content asynchronously
      const fileBuffer = await fs.readFile(filePath);
      
      // Create a new FormData instance
      const formData = new FormData();
  
      // Append the file to the FormData instance
      // 'file' is the field name that the server expects for the uploaded file
      formData.append('file', fileBuffer, fileName);
  
      // Perform the fetch request to upload the file
      const response = await fetch(uploadUrl, {
        method: 'POST',
        body: formData, // Automatically sets 'Content-Type': 'multipart/form-data'
      });
  
      // Check the response
      if (!response.ok) {
        throw new Error(`Server responded with ${response.status}: ${response.statusText}`);
      }
  
      console.log(`Successfully uploaded ${fileName}`);
    } catch (error) {
      console.error('Error uploading file:', error);
    }
}

// POST route for handling file uploads
app.post('/upload', (req, res) => {
    const form = new formidable.IncomingForm();
  
    // File upload directory
    form.uploadDir = uploadDirectory;
  
    form.parse(req, (err, fields, files) => {
      if (err) {
        console.error('Error processing upload:', err);
        return res.status(500).send('An error occurred during the upload.');
      }
      // Log uploaded file info
      console.log('Uploaded file:', files.file);
      res.status(200).send('File uploaded successfully.');
    });
  });

// GET route for displaying uploaded files
app.get('/', (req, res) => {
    fs.readdir(uploadDirectory, (err, files) => {
        if (err) {
            console.error('Failed to list upload directory:', err);
            return res.sendStatus(500);
        }

        let fileLinks = files.map(file => `<li>${file}</li>`).join('');
        res.send(`
            <h2>Uploaded Files</h2>
            <ul>${fileLinks}</ul>
        `);
    });
});

// Start the server
app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
    console.log('Monitoring files saved to ' + targetDirectory + '\n');
});

我从能够将文件从一个目录移动到另一个目录的代码开始,但希望将来能够在服务器上执行此操作。我无法让它发挥作用。

node.js file-upload server
1个回答
0
投票

fs.readFile 除外未在代码中定义的回调函数,因此您会收到未定义的 cb 错误

const fileBuffer = await fs.readFile(filePath);

您可以切换到使用 readFileSync,如下所示

const fileBuffer = fs.readFileSync(filePath);

按照此链接阅读有关 readFileSync 的更多信息

© www.soinside.com 2019 - 2024. All rights reserved.