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

如何解决Node.js服务返回text/html MIME类型导致JS模块加载失败问题

错误根因

  1. 你当前写的Node服务对所有请求统一返回index.html文件,且固定设置Content-Type为text/html。当浏览器请求src/js/main.js这个JS模块时,拿到的是HTML内容,MIME类型不匹配,直接触发规范要求的严格校验报错。
  2. 还有个隐藏问题:yahoo-finance2的服务端能力不能直接在浏览器端运行,你现在把yahoo-finance2的调用写在前端main.js里,就算解决了MIME问题也无法正常获取数据,必须把这部分逻辑移到服务端做代理接口。

具体修复步骤

第一步:修改server.js 支持静态资源返回与API代理

import * as http from "http";
import * as fs from "fs";
import * as path from "path";
import yahooFinance from "yahoo-finance2";

const hostname = "127.0.0.1";
const port = 3000;

// 配置不同后缀对应的MIME类型
const mimeTypes = {
  '.html': 'text/html',
  '.js': 'application/javascript',
  '.css': 'text/css',
  '.json': 'application/json',
  '.png': 'image/png',
  '.jpg': 'image/jpeg',
  '.gif': 'image/gif',
  '.svg': 'image/svg+xml'
};

const server = http.createServer(async function (req, res) {
  // 处理股票数据API代理请求
  if (req.url.startsWith('/api/historical')) {
    const urlParams = new URL(req.url, `http://${hostname}:${port}`);
    const symbol = urlParams.searchParams.get('symbol');
    const start = urlParams.searchParams.get('start');
    const end = urlParams.searchParams.get('end');
    const interval = urlParams.searchParams.get('interval');

    try {
      const queryOptions = {
        period1: new Date(start),
        period2: new Date(end),
        interval: interval,
      };
      const result = await yahooFinance.historical(symbol, queryOptions);
      const resultWithSymbol = result.map(item => ({ ...item, symbol }));
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify(resultWithSymbol));
    } catch (err) {
      res.writeHead(500, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ error: err.message }));
    }
    return;
  }

  // 处理静态资源请求
  let filePath = '.' + req.url;
  if (filePath === './') {
    filePath = './index.html';
  }

  const extname = String(path.extname(filePath)).toLowerCase();
  const contentType = mimeTypes[extname] || 'application/octet-stream';

  fs.readFile(filePath, (error, content) => {
    if (error) {
      if(error.code === 'ENOENT') {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end('Whoops! File not found!', 'utf-8');
      } else {
        res.writeHead(500);
        res.end('Server Error: ' + error.code, 'utf-8');
      }
    } else {
      res.writeHead(200, { 'Content-Type': contentType });
      res.end(content, 'utf-8');
    }
  });
});

server.listen(port, hostname, function (error) {
  if (error) {
    console.log("Something went wrong", error);
  } else {
    console.log("Server running at http://" + hostname + ":" + port + "/");
  }
});

第二步:修改前端main.js 移除服务端包引用,改为调用本地接口

async function api(symbol, start, end, val) {
  try {
    // 调用自己的Node服务代理接口
    const response = await fetch(`/api/historical?symbol=${symbol}&start=${start}&end=${end}&interval=${val}`);
    const resultWithSymbol = await response.json();
    console.log(resultWithSymbol);
    return resultWithSymbol;
  } catch (err) {
    console.error('请求失败:', err);
  }
}

api("TSLA", "2021-08-02", "2021-08-14", "1d");

第三步:调整文件路径

如果你的index.html放在src目录下,需要把server.js里的静态资源根目录调整为./src;或者先执行npm run build打包项目,再把server.js里的静态资源路径改为./dist,直接serve打包后的产物。

运行方式

执行npm run start启动服务,访问http://127.0.0.1:3000即可正常加载资源、获取股票数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:51:01