Astro框架下区块链交互的JS模块与事件监听问题
问题场景
我正在跟随Richard Gottleber的教程,使用Chainlink和ethers.js基于Astro框架开发去中心化新闻服务,已完成教程中的合约读取功能,正尝试进一步扩展以适配黑客松项目。下一步需要执行写交易,触发sendRequest函数获取新新闻文章,但所有尝试均失败,目前暂时切换到Scaffold-Eth。
项目配置:
- 框架:Astro
- 库:ethers.js、Chainlink
- 教程参考:Richard Gottleber的区块链开发者JavaScript大师班
- 仓库链接:分布式新闻工作坊
目标:
扩展教程功能,通过sendRequest函数获取更多文章,触发展示内容更新,同时集成Chainlink的RNG以增加随机性和D&D风格。
当前状态:
初始数据可正常展示,但添加按钮点击获取更多文章的动态功能无法生效。
遇到的问题:
- JavaScript模块管理:在HTML中使用模块语法时,ethers.js无法被识别。
- 事件处理:已从HTML的onclick属性切换为通过JavaScript添加事件监听器,以确保加载顺序和作用域解析正确。
- 404错误:移动函数定义(将sendRequest从独立模块移入newsArchive.js)时,出现文件未找到错误。
- 安全顾虑:将JavaScript文件移至公共目录解决路径问题时,担心敏感环境变量暴露。
错误信息:
- 将写调用代码移入sendRequest.js或newArchive.js时,出现
404 Not Found GET http://localhost:4321/lib/sendRequest.js net::ERR_ABORTED 404 (Not Found)(index):4 Uncaught ReferenceError: handleButtonClick is not defined at HTMLButtonElement.onclick ((index):4:1611)Uncaught TypeError: Failed to resolve module specifier "ethers". Relative references must start with either "/", "./", or "../".
代码示例(简化版,突出问题部分):
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.jsdelivr.net/npm/ethers/dist/ethers.min.js"></script> </head> <body> <nav> <button id="fetchButton">Fetch More, Chainlink</button> </nav> <script type="module"> import { sendRequest } from '/newsArchive.js'; document.addEventListener('DOMContentLoaded', function() { document.getElementById('fetchButton').addEventListener('click', async function() { console.log('Fetching more articles...'); try { const newArticles = await sendRequest(); console.log('New articles fetched:', newArticles); } catch (error) { console.log('error fetching new articles', error); } }); }); </script> </body> </html>
问题:
- 在Astro项目中,需要与以太坊区块链交互时,正确的JavaScript模块管理方式是什么?
- 如何确保ethers.js在自定义脚本的函数中被正确加载和访问?
- 将脚本移至公共目录时,有哪些最佳实践可防止敏感环境变量暴露?
目前计划将代码迁移到Scaffold-Eth继续开发。
已尝试的修复方案
- JavaScript模块管理
- 移动文件:最初newsArchive.js等文件位于src/lib目录,为解决模块路径问题,尝试将其移至Astro项目的public目录,期望客户端脚本可更易访问。
- 修改脚本标签:切换script标签的type属性,在module和text/javascript之间来回调整,试图解决浏览器无法识别ES模块导入的问题。
- 使用CDN加载:由于作为模块导入时ethers.js无法被识别,改为在HTML头部通过CDN加载,确保其在项目中全局可用,无需导入语句。
- 事件处理
- 从内联切换到监听器:最初使用HTML标签内的onclick属性处理交互,改为通过JavaScript添加事件监听器,确保DOM完全加载且必要脚本初始化后再绑定。
- 使用DOMContentLoaded:将事件监听器包裹在DOMContentLoaded事件中,避免在页面完全加载前初始化,防止时序问题。
- 错误处理与调试
- 控制台日志与调试:添加大量控制台日志跟踪流程,定位ethers.js函数和AJAX调用的失败点。
- 网络与控制台监控:使用浏览器开发者工具监控脚本加载的网络请求,检查控制台中的即时JavaScript错误。
- 文件路径与导入问题
- 调整路径:多次调整导入语句中的路径,尝试相对路径和绝对路径,以解决404错误。
- 重定位脚本:在HTML文档中尝试不同的脚本位置,以更有效地管理加载顺序。
- 安全顾虑
- 环境变量:评估将可能包含敏感信息的脚本移至公共目录的影响,确保客户端脚本中不包含敏感密钥或令牌,避免泄露。
仍存在的问题
尽管进行了上述尝试,仍面临以下问题:
- Ethers未定义:即使通过CDN加载ethers.js,仍会间歇性出现其他脚本无法识别它的问题。
- 无法获取文章:当前获取文章的调用要么静默失败,要么因脚本错误无法触发。
- 点击事件异常:无法触发sendRequest,不确定是否存在问题连锁阻塞。
内容的提问来源于stack exchange,提问作者Tippi Fifestarr
相关产品推荐
相关产品推荐

