JavaScript获取Jupyter Notebook代码单元格内容报错:Jupyter未定义
问题:"ReferenceError: Jupyter is not defined" 报错处理
场景与报错
编写JavaScript代码用于收集Jupyter Notebook中代码单元格内容并发送至外部服务器,代码如下:
function sendNewData() { let cells = Jupyter.notebook.get_cells(); let actualCells = []; cells.forEach(function (cell) { if(cell.cell_type == "code" && cell.metadata.created) { let creationTime = new Date(cell.metadata.created); let timeDiff = seminarStartedDate - creationTime; if (timeDiff > 0) { actualCells.push(cell.get_text()); } } }) let url = "https://localhost:7199/Seminar/students/" + seminarId + "/" + studentId; const response = fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(actualCells), }) console.log("sent data"); }
运行后报错:ReferenceError: Jupyter is not defined at sendNewData
原因分析
网上资料里的Jupyter.notebook是**经典Jupyter Notebook(6.x及更早版本)**的前端API,在新版Notebook(7.x+)或JupyterLab中,前端架构进行了更新,全局Jupyter变量已被移除,替换为jupyter全局对象,所以直接调用Jupyter.notebook会导致未定义错误——并非API被停用,而是命名空间发生了变更。
另外需要注意:这段代码必须在浏览器前端上下文中运行(比如开发者控制台、自定义前端扩展),如果在Notebook的代码单元格中直接执行,会因为运行环境是内核(而非页面前端)而无法访问页面全局对象。
解决方案
1. 适配新版Notebook/JupyterLab
将代码中的Jupyter.notebook替换为jupyter.notebook,修改后的代码如下:
function sendNewData() { // 替换全局对象命名空间 let cells = jupyter.notebook.get_cells(); let actualCells = []; cells.forEach(function (cell) { if(cell.cell_type == "code" && cell.metadata.created) { let creationTime = new Date(cell.metadata.created); let timeDiff = seminarStartedDate - creationTime; if (timeDiff > 0) { actualCells.push(cell.get_text()); } } }) let url = "https://localhost:7199/Seminar/students/" + seminarId + "/" + studentId; const response = fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(actualCells), }) console.log("sent data"); }
2. 兼容新旧版本(可选)
如果需要同时兼容新旧版本,可以添加全局对象的判断:
function sendNewData() { // 兼容新旧版本的全局对象 const notebookApp = window.Jupyter || window.jupyter; if (!notebookApp?.notebook) { console.error("无法获取Notebook实例"); return; } let cells = notebookApp.notebook.get_cells(); let actualCells = []; cells.forEach(function (cell) { if(cell.cell_type == "code" && cell.metadata.created) { let creationTime = new Date(cell.metadata.created); let timeDiff = seminarStartedDate - creationTime; if (timeDiff > 0) { actualCells.push(cell.get_text()); } } }) let url = "https://localhost:7199/Seminar/students/" + seminarId + "/" + studentId; const response = fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(actualCells), }) console.log("sent data"); }
3. 确保运行环境正确
- 打开Notebook页面后,按F12打开浏览器开发者控制台,将代码粘贴到控制台中执行;
- 如果需要长期使用,可将代码封装为Jupyter Notebook的前端扩展,通过扩展机制加载到页面中。
内容的提问来源于stack exchange,提问作者Григорий Дьяконов
相关产品推荐
相关产品推荐

