
本文详解如何在本地开发环境中正确加载并初始化 GLPK.js,解决常见的 CORS 阻塞和 Uncaught ReferenceError: glpk is not defined 等典型错误,涵盖本地文件引入与 CDN 引入两种可靠方案。
本文详解如何在本地开发环境中正确加载并初始化 glpk.js,解决常见的 cors 阻塞和 `uncaught referenceerror: glpk is not defined` 等典型错误,涵盖本地文件引入与 cdn 引入两种可靠方案。
GLPK.js 是一个基于 WebAssembly 的线性规划求解器,可在浏览器中直接运行 GLPK(GNU Linear Programming Kit)。但因其模块设计与浏览器安全策略限制,开发者常遇到两类核心问题:一是本地 file:// 协议下因 CORS 策略导致脚本无法加载;二是误用 ES 模块导入方式,导致 glpk 全局对象未定义或命名导出不匹配。以下提供经验证的、生产就绪的解决方案。
✅ 方案一:本地引入(推荐用于离线/内网环境)
禁止使用 import 语句加载本地 .js 文件(如 import GLPK from './dist/glpk.min.js'),因为浏览器在 file:// 协议下会拒绝跨源请求,触发如下错误:
Access to script at 'file:///.../glpk.min.js' from origin 'null' has been blocked by CORS policy...
✅ 正确做法是使用传统 <script></script> 标签同步加载,并依赖其自动挂载的全局 initGLPK 函数:
<script src="./dist/glpk.min.js"></script><script type="module">
(async () => {
const glpk = await initGLPK(); // 注意:不是 GLPK(),而是 initGLPK()
// 后续调用示例(如运输问题求解)
const lp = {
name: 'Transportation Problem',
objective: { direction: glpk.GLP_MIN, name: 'obj', vars: [...] },
subjectTo: [...]
};
const solution = await glpk.solve(lp, { msglev: glpk.GLP_MSG_OFF });
console.log('Optimal solution:', solution);
})();
</script>
⚠️ 注意事项:
-
glpk.min.js必须通过本地 Web 服务器(如http-server、live-server或 VS Code Live Server 插件)提供服务,不能双击 HTML 文件直接打开; - 若坚持使用
file://协议,需启动 Chrome 时添加启动参数禁用 CORS(仅限开发调试):chrome.exe --user-data-dir="/tmp/chrome_dev" --disable-web-security
✅ 方案二:CDN 引入(推荐用于快速原型与在线演示)
CDN 上的 glpk.min.js 并非标准 ES 模块(无 export default),因此 import GLPK from '...' 会报错:
Uncaught SyntaxError: The requested module ... does not provide an export named 'default'
✅ 正确方式是使用 命名导入语法 import { initGLPK } from '...',或更简洁地采用默认导入别名(因 CDN 版本实际导出的是 initGLPK 函数):
<script type="module">
// ✅ 推荐:显式导入 initGLPK(语义清晰,兼容性强)
import { initGLPK } from 'https://cdn.jsdelivr.net/npm/glpk@1.0.3/dist/glpk.min.js';
(async () => {
const glpk = await initGLPK();
// 示例:构建并求解最小成本运输问题
const supply = [20, 30, 25];
const demand = [10, 25, 20, 20];
const costs = [[8,6,10,9], [9,12,13,7], [14,9,16,5]];
const variables = [];
for (let i = 0; i < supply.length; i++) {
for (let j = 0; j < demand.length; j++) {
variables.push({ name: `x_${i}_${j}`, coef: costs[i][j] });
}
}
const constraints = [];
// 供应约束(等式:∑x_ij = supply_i)
supply.forEach((s, i) => {
constraints.push({
name: `supply_${i}`,
vars: Array.from({ length: demand.length }, (_, j) => ({ name: `x_${i}_${j}`, coef: 1 })),
bnds: { type: glpk.GLP_FX, lb: s, ub: s }
});
});
// 需求约束(等式:∑x_ij = demand_j)
demand.forEach((d, j) => {
constraints.push({
name: `demand_${j}`,
vars: Array.from({ length: supply.length }, (_, i) => ({ name: `x_${i}_${j}`, coef: 1 })),
bnds: { type: glpk.GLP_FX, lb: d, ub: d }
});
});
const lp = {
name: 'Transportation Problem',
objective: { direction: glpk.GLP_MIN, name: 'obj', vars: variables },
subjectTo: constraints
};
const result = await glpk.solve(lp, { msglev: glpk.GLP_MSG_OFF });
console.log('Solution status:', result.status); // e.g., "opt"
console.log('Objective value:', result.objval);
})();
</script>
? 补充说明:
-
glpk@1.0.3是当前稳定版本(请以 npmjs.com/package/glpk 最新版本为准); -
initGLPK()返回 Promise,内部完成 WebAssembly 初始化,*必须 await 后才能使用 `glpk.` API**; - 所有常量(如
glpk.GLP_MIN,glpk.GLP_FX)均在glpk实例上定义,不可提前引用。
✅ 总结
| 场景 | 正确加载方式 | 关键要点 |
|---|---|---|
| 本地开发(离线) |
<script src="./dist/glpk.min.js"></script> + await initGLPK()
|
避免 file:// 协议,启用本地 HTTP 服务 |
| 在线演示 / 快速测试 | import { initGLPK } from 'https://cdn.jsdelivr.net/.../glpk.min.js' |
不要 import GLPK from ...,不支持 default export |
只要遵循上述任一规范,即可彻底规避 glpk is not defined 和 CORS 报错,稳定调用 GLPK.js 求解线性规划与整数规划问题。











