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

使用Snowpack与React无法访问Express接口的问题求助

问题:Node.js集成Express+Snowpack+React应用中Axios无法请求Express接口

基于Node.js搭建了集成Express、Snowpack与React的Web应用,页面视图可正常加载,但无法通过axios请求指定的Express接口。请求中的接口URL指向服务器正确,去掉/api/test可正常打开视图,尝试过仅用/api/test或localhost地址,仍无法访问目标接口。目前无法访问路由中的/test与/api/test接口,仅前端视图相关的目录路由可用,怀疑Snowpack未使用Express路由,而是通过自身配置挂载目录提供视图,不确定根目录的app.js是否仍在运行服务器,希望得到问题排查方向或解决方法。

React组件代码

import React, { useState } from 'react';
import axios from 'axios';

// form component
const MyForm = () => {
  // state variable that triggers component render/handles state and variables related to form
  const [formData, setFormData] = useState({
    username: '',
    password: ''
  });

  // function that handles when data in the form is changed
  const handleChange = (event) => {
    setFormData({ ...formData, [event.target.name]: event.target.value });
  };

  // function that handles when the form is submitted
  const handleSubmit = async (event) => {
    event.preventDefault();
    console.log('Form submitted on client side:', formData);
    console.log("Attempting to send form data to server.");
    try {
      const response = await axios.post('http://10.0.0.121:8080/api/test', formData);
      console.log('Server response: ', response.data);
    } catch (error) {
      console.error('Error communicating with server: ', error);
    }

    setFormData({ username: '', password: '' });
  };

  // Html of the component
  return (
    <form id="Lform" onSubmit={handleSubmit}>
      <table>
        <tr>
          <td><label id="Uname">Username</label></td>
          <td><input type="text" name="username" value={formData.username} onChange={handleChange} required/></td>
        </tr>
        <tr>
          <td><label id="Pword">Password</label></td>
          <td><input type="password" name="password" value={formData.password} onChange={handleChange} required/></td>
        </tr>
      </table>
      <button type="submit">Submit</button>
    </form>
  );
};

Express路由代码(router.js)

const express = require('express');
const cors = require('cors');
var path = require('path')
const router = express.Router();

router.use(cors());
router.use(express.json());

router.get('/', function(req, res){
    res.sendFile(path.join(__dirname, 'public', "index.html"));
});

router.get('/index.js', function(req, res){
    res.sendFile(path.join(__dirname,'index.js'));
});

router.get('/src/*', (req, res) =>{
     res.sendFile(path.join(__dirname, 'src', req.params[0]));
 });

router.post('/api/test', (req, res)=>{
  const clientData = req.body;
  res.send("Communication with server successful: ", JSON.stringify(clientData));
});

router.get('/test', (req, res) =>{
    res.sendFile(path.join(__dirname,'test.html'));
});

router.use(express.static('public'));

module.exports = router;

根目录app.js代码

var express = require('express');
var http = require('http');
const cors = require('cors');
// import mongoose later
var app = express();
const routes = require('./router');

app.use(cors());
app.use('/', routes);
app.use(express.json());

const server = http.createServer(app);

const port = process.env.PORT ?? 443;

server.listen(port);

console.log("root directory is: " + __dirname)

console.log(`server is on http://localhost:${port}`);

排查方向与解决方法

1. 端口不匹配问题(核心)

前端Axios请求用的是8080端口,但Express服务器默认监听443端口(app.js中port = process.env.PORT ?? 443),端口不一致导致请求无法到达Express服务:

  • 方案一:修改app.js的监听端口为8080,和前端请求一致:
    const port = process.env.PORT ?? 8080;
    
  • 方案二:修改前端请求地址为Express实际监听的端口,比如如果是443,请求地址改为http://10.0.0.121:443/api/test(若配置了HTTPS则用https)。

2. Snowpack代理配置

Snowpack开发服务器默认单独运行(端口8080),此时前端请求Express服务会触发跨域,且Snowpack不会自动转发请求。需要在snowpack.config.js中添加代理规则:

module.exports = {
  proxy: {
    '/api': {
      target: 'http://localhost:443', // 替换为你的Express服务地址+端口
      changeOrigin: true,
    },
    '/test': {
      target: 'http://localhost:443',
      changeOrigin: true,
    }
  },
};

之后前端Axios改用相对路径请求:

const response = await axios.post('/api/test', formData);

3. Express中间件与路由修正

  • 请求体解析顺序错误:app.js中app.use(express.json())放在了路由之后,导致Express无法解析POST请求的JSON体,需调整顺序:
    app.use(cors());
    app.use(express.json()); // 移到路由之前
    app.use('/', routes);
    
  • res.send参数错误:router.js中res.send不能传递多个参数,需修改为模板字符串:
    res.send(`Communication with server successful: ${JSON.stringify(clientData)}`);
    
  • 重复中间件:router.js中router.use(express.json())可删除,因为app.js已配置全局的JSON解析中间件。

4. 确认服务运行状态

  • 启动Express服务:确保node app.js已正常运行,控制台输出server is on http://localhost:xxx。
  • 开发环境运行方式:若同时使用Snowpack开发服务器和Express,需确保两个服务都在启动状态;若生产环境,需将Snowpack编译后的静态资源(默认build目录)交给Express托管,替换router.js中的静态资源路由:
    router.use(express.static(path.join(__dirname, 'build')));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:35:07