You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express.js中实现无页面跳转的请求获取及文件系统操作?

Hey there! Let's break down how to solve your two related problems—keeping your page from navigating away while handling file system operations in Express. Here's a step-by-step solution tailored to your existing code:

Why Your Current Code Triggers Page Jumps

Right now, your /todo/download and /todo/upload routes send back plain text ("download page") which would replace your current page if accessed via a link or form submit. Instead, we need to:

  • Use asynchronous requests from the frontend (so the browser doesn't reload)
  • Update the Express routes to handle actual file system work and return responses that play nice with those async calls

Step 1: Refactor Your Express Backend

Let's adjust your code to handle real file operations and return appropriate responses:

let express = require('express');
let fs = require('fs'); // Lowercase for standard JS convention
let path = require('path');
let app = express();
let router = express.Router();
const port = 2020;

// Add middleware to parse request data (critical for uploads)
app.use(express.static('Programs'));
app.use(express.json()); // Parse JSON request bodies
app.use(express.urlencoded({ extended: true })); // Parse form data
app.use('/', router);

// Serve your main page (unchanged)
router.get('/', (req, res) => { 
  res.sendFile(path.join(__dirname + '/views/UiOfServer.html')); 
});

// Handle download: Stream a file to the client without page reload
router.get('/todo/download', (req, res) => {
  // Replace this with your actual file path
  const targetFile = path.join(__dirname, '/storage/your-file-to-download.txt');

  // First check if the file exists
  fs.access(targetFile, fs.constants.F_OK, (err) => {
    if (err) {
      return res.status(404).json({ success: false, message: 'File not found' });
    }

    // Set headers to trigger a download prompt without page change
    res.setHeader('Content-Disposition', 'attachment; filename="my-download.txt"');
    res.setHeader('Content-Type', 'text/plain');

    // Stream the file to the client (efficient for large files)
    const fileStream = fs.createReadStream(targetFile);
    fileStream.pipe(res);
  });
});

// Handle upload: Save content to the filesystem
router.post('/todo/upload', (req, res) => {
  // For this example, we'll accept text content from the frontend
  // For binary files, use the `multer` package (see tip below)
  const uploadText = req.body.uploadContent;
  const savePath = path.join(__dirname, '/uploads/saved-upload.txt');

  fs.writeFile(savePath, uploadText, (err) => {
    if (err) {
      return res.status(500).json({ success: false, message: 'Failed to save file' });
    }
    res.json({ success: true, message: 'File uploaded successfully!' });
  });
});

app.listen(port, (err) => { 
  if(err){ 
    console.log(`Server Error: ${err}`); 
  } else{ 
    console.log(`Server running on port ${port}`); 
  } 
});

Step 2: Update Your Frontend (UiOfServer.html)

Add JavaScript to your HTML to handle button clicks with fetch—this sends requests in the background without reloading the page:

<!DOCTYPE html>
<html>
<head>
  <title>Server File Ops</title>
</head>
<body>
  <h1>File Operations</h1>
  <button id="downloadBtn">Download File</button>
  <div style="margin: 20px 0;">
    <textarea id="uploadInput" rows="5" cols="50" placeholder="Enter text to upload..."></textarea>
    <br>
    <button id="uploadBtn">Upload Text</button>
  </div>
  <div id="statusMessage" style="color: blue;"></div>

  <script>
    const downloadBtn = document.getElementById('downloadBtn');
    const uploadBtn = document.getElementById('uploadBtn');
    const statusMsg = document.getElementById('statusMessage');
    const uploadInput = document.getElementById('uploadInput');

    // Handle Download Click
    downloadBtn.addEventListener('click', async () => {
      try {
        const response = await fetch('/todo/download');
        if (!response.ok) throw new Error('Download failed');
        
        // Convert response to blob and trigger browser download
        const blob = await response.blob();
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = 'my-download.txt';
        document.body.appendChild(link);
        link.click();
        // Clean up
        window.URL.revokeObjectURL(downloadUrl);
        document.body.removeChild(link);

        statusMsg.textContent = 'Download started successfully!';
      } catch (err) {
        statusMsg.textContent = `Error: ${err.message}`;
      }
    });

    // Handle Upload Click
    uploadBtn.addEventListener('click', async () => {
      const content = uploadInput.value.trim();
      if (!content) {
        statusMsg.textContent = 'Please enter text to upload first!';
        return;
      }

      try {
        const response = await fetch('/todo/upload', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ uploadContent: content })
        });

        const result = await response.json();
        statusMsg.textContent = result.message;
        if (result.success) uploadInput.value = ''; // Clear input on success
      } catch (err) {
        statusMsg.textContent = `Upload error: ${err.message}`;
      }
    });
  </script>
</body>
</html>

Quick Extra Tips

  • Binary File Uploads: If you need to upload actual files (images, PDFs, etc.), use the multer npm package in Express—it handles multipart/form-data requests seamlessly.
  • Error Handling: The code includes basic error handling to give users feedback without breaking the page. You can expand this to fit your needs.
  • Security: Always validate and sanitize user input/file paths to prevent path traversal attacks (never use raw user input to construct file paths directly!).

内容的提问来源于stack exchange,提问作者Hessam Hosseini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:52:46