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

如何在服务端构建文件读取数组并传入客户端script.js?

可行方案实现指南

方案1:EJS模板直接注入数据(适配你已尝试的技术栈)

既然你已经在用Node.js+EJS,这是最直接的实现方式,能满足「每次请求页面时服务端读取文件」的需求:

1. 服务端代码(示例:app.js)

先读取文件生成数组,再把数据传给EJS模板:

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

// 配置EJS模板引擎
app.set('view engine', 'ejs');
// 托管静态文件(style.css、script.js放public文件夹)
app.use(express.static('public'));

// 定义两个列表文件的路径
const list1Path = './list1.txt';
const list2Path = './list2.txt';

app.get('/', (req, res) => {
    // 读取文件并转成数组,同时过滤空行
    const list_1 = fs.readFileSync(list1Path, 'utf-8')
        .split('\n')
        .filter(line => line.trim() !== '');
    const list_2 = fs.readFileSync(list2Path, 'utf-8')
        .split('\n')
        .filter(line => line.trim() !== '');
    
    // 把数组传给EJS模板
    res.render('index', { list1: list_1, list2: list_2 });
});

app.listen(3000, () => console.log('服务运行在3000端口'));

2. 修改index.html为EJS模板(index.ejs)

在页面中通过EJS标签把服务端数据注入成客户端全局变量,这样script.js就能直接调用:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/style.css">
</head>
<body>
    <button id="canBtn">切换列表</button>
    <p class="tag-line"></p> <!-- 补充原代码提到的tagLine元素 -->
    <section class="text-container"></section>

    <!-- 注入服务端数据为全局变量 -->
    <script>
        const list_1 = <%- JSON.stringify(list1) %>;
        const list_2 = <%- JSON.stringify(list2) %>;
    </script>
    <script src="/script.js"></script>
</body>
</html>

这里用<%- %>是为了输出未转义的JSON,确保能直接转为JS数组。

3. 客户端script.js(去除硬编码逻辑)

保留原有切换逻辑,直接使用全局变量:

const canBtn = document.getElementById('canBtn');
const tagLine = document.querySelector('.tag-line');
const textContainer = document.querySelector('.text-container');
let currentList = list_1;

// 渲染列表的通用函数
function renderList(list) {
    textContainer.innerHTML = ''; // 清空容器
    list.forEach(el => {
        const div = document.createElement('div');
        div.innerText = el;
        textContainer.appendChild(div);
    });
}

// 初始化渲染
canBtn.innerText = "CAN'T";
tagLine.innerText = 'I can still ...';
renderList(currentList);

// 按钮切换逻辑
canBtn.addEventListener('click', () => {
    currentList = currentList === list_1 ? list_2 : list_1;
    canBtn.innerText = currentList === list_1 ? "CAN'T" : "CAN";
    renderList(currentList);
});

方案2:API接口+客户端Fetch(更符合单页应用异步逻辑)

如果不想依赖模板注入,也可以通过API接口返回数据,客户端异步请求,适合后续扩展:

1. 服务端添加API路由(app.js中补充)

app.get('/api/lists', (req, res) => {
    const list_1 = fs.readFileSync(list1Path, 'utf-8')
        .split('\n')
        .filter(line => line.trim() !== '');
    const list_2 = fs.readFileSync(list2Path, 'utf-8')
        .split('\n')
        .filter(line => line.trim() !== '');
    
    res.json({ list1: list_1, list2: list_2 });
});

2. 客户端script.js(异步请求数据)

去掉硬编码数组,改为加载页面时请求API:

const canBtn = document.getElementById('canBtn');
const tagLine = document.querySelector('.tag-line');
const textContainer = document.querySelector('.text-container');
let list_1, list_2, currentList;

// 加载列表数据
async function loadLists() {
    try {
        const response = await fetch('/api/lists');
        const data = await response.json();
        list_1 = data.list1;
        list_2 = data.list2;
        currentList = list_1;
        
        // 初始化渲染
        canBtn.innerText = "CAN'T";
        tagLine.innerText = 'I can still ...';
        renderList(currentList);
        
        // 绑定切换事件
        canBtn.addEventListener('click', toggleList);
    } catch (err) {
        console.error('加载列表失败:', err);
    }
}

function renderList(list) {
    textContainer.innerHTML = '';
    list.forEach(el => {
        const div = document.createElement('div');
        div.innerText = el;
        textContainer.appendChild(div);
    });
}

function toggleList() {
    currentList = currentList === list_1 ? list_2 : list_1;
    canBtn.innerText = currentList === list_1 ? "CAN'T" : "CAN";
    renderList(currentList);
}

// 页面加载时执行
window.addEventListener('load', loadLists);

新手提示

  • 读取文件时加filter(line => line.trim() !== ''),可以避免文件末尾的空行被加入数组。
  • 方案1的优势是页面加载时直接有数据,无需等待异步请求;方案2更灵活,适合后续需要动态刷新数据的场景。
  • 确保静态文件(style.css、script.js)放在public文件夹下,服务端通过app.use(express.static('public'))托管才能访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:03:21