内联JS可正常运行,如何让外部app.js在IPFS/Pinata环境下工作?
问题与解决方案:IPFS/Pinata部署后外部JS无法加载导致功能失效
问题背景
开发基于IPFS和Pinata的网站,原内联JS版本在本地/公共网关正常运行,但Pinata禁止使用内联JS,遂将JS代码提取至同目录的app.js文件。上传IPFS后,HTML页面可正常显示,但按钮点击功能完全失效,调用JS文件时持续返回400/500错误,尝试多种路径均无法解决。
调用JS的代码:
<script type="text/javascript" src="app.js"></script>
现有代码
HTML代码
<!DOCTYPE html> <html> <head> <title>LootCache</title> <script type="text/javascript" src="app.js"></script> <style> body { background-color: black; margin: 0; padding: 0; } .container { max-width: 100%; margin: 0 auto; border: 5px solid gold; padding: 10px; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; height: 100vh; overflow: auto; } h1 { font-size: 50px; font-weight: bold; color: gold; margin: 10px 0; display: flex; align-items: center; } .input-container { background-color: white; padding: 10px; margin: 10px 0; border-radius: 5px; display: flex; flex-direction: column; align-items: center; width: 100%; box-sizing: border-box; max-width: 800px; } input[type=text] { width: 100%; padding: 10px; border: none; border-radius: 5px; box-sizing: border-box; font-size: 16px; margin-bottom: 10px; } button { background-color: gold; color: black; border: none; border-radius: 5px; padding: 10px; font-size: 16px; cursor: pointer; } .response { color: gold; font-size: 20px; margin-top: 10px; word-wrap: break-word; text-align: center; } img { display: block; max-height: calc(100vh - 300px); margin: 10px auto; object-fit: contain; max-width: 100%; height: auto; } </style> </head> <body> <div class="container"> <img src="https://ipfs.io/ipfs/QmXjtBuhfDRZfTXZjF2dpJ4mSnmjj5RPow4qMY5X6ZQ6QU?filename=LootCache-1.png" alt="LootCache"> <h1></h1> <div class="input-container"> <label for="ethAddress">Enter Ethereum Address (No ENS):</label> <input type="text" id="ethAddress" name="ethAddress" placeholder="0x..."> <button id="checkBalanceBtn">Check Your Stash!</button> </div> <div class="response" id="response"></div> </div> </body> </html>
JS代码(app.js)
window.onload = function() { async function getBalance(address) { const response = await fetch(`https://mainnet.infura.io/v3/fb3bba54ae0449c28400a4e28fb61e6c?module=account&action=balance&address=${address}`); const data = await response.json(); return data.result; } function displayAddress() { var address = document.getElementById("ethAddress").value; var provider = new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/fb3bba54ae0449c28400a4e28fb61e6c"); var web3 = new Web3(provider); web3.eth.getBalance(address, function(error, balance) { if (error) { document.getElementById("response").innerHTML = "Error: " + error.message; } else { var balanceInEther = web3.utils.fromWei(balance, "ether"); var formattedBalance = parseFloat(balanceInEther).toFixed(4); document.getElementById("response").innerHTML = "Address: " + address + "<br>Balance: " + formattedBalance + " ETH"; } }); } }
核心问题与修复步骤
1. 函数作用域问题(直接导致按钮失效)
displayAddress函数被包裹在window.onload的回调内部,全局作用域无法访问该函数,按钮点击时找不到对应的处理逻辑。
修复方法:在window.onload内部直接绑定按钮的点击事件,无需依赖全局函数:
window.onload = function() { async function getBalance(address) { const response = await fetch(`https://mainnet.infura.io/v3/fb3bba54ae0449c28400a4e28fb61e6c?module=account&action=balance&address=${address}`); const data = await response.json(); return data.result; } function displayAddress() { var address = document.getElementById("ethAddress").value; var provider = new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/fb3bba54ae0449c28400a4e28fb61e6c"); var web3 = new Web3(provider); web3.eth.getBalance(address, function(error, balance) { if (error) { document.getElementById("response").innerHTML = "Error: " + error.message; } else { var balanceInEther = web3.utils.fromWei(balance, "ether"); var formattedBalance = parseFloat(balanceInEther).toFixed(4); document.getElementById("response").innerHTML = "Address: " + address + "<br>Balance: " + formattedBalance + " ETH"; } }); } // 绑定按钮点击事件 document.getElementById("checkBalanceBtn").addEventListener("click", displayAddress); }
2. 缺失Web3依赖
代码中使用了Web3对象,但HTML未引入Web3库,导致JS执行报错。
修复方法:在HTML的<head>中添加Web3的CDN引用,放在app.js之前:
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script> <script type="text/javascript" src="app.js"></script>
3. IPFS上传与路径问题
- 必须将
index.html和app.js放在同一文件夹中整体上传至IPFS,而非单独上传文件。IPFS的相对路径依赖于同一目录的CID,单独上传会导致文件CID不同,相对路径失效。 - 验证JS文件可访问性:打开页面后,在浏览器控制台的Network标签查看
app.js的请求状态,若显示404,说明路径错误,需确认上传的目录结构是否正确。
4. 网关与CORS排查
若仍有错误,打开浏览器控制台的Console标签查看具体报错信息:
- 若提示
Web3 is not defined:确认Web3库已正确加载。 - 若提示404:检查IPFS网关的JS文件路径是否正确。
- 若提示CORS错误:确认Infura接口允许跨域请求(Infura默认支持,若问题持续可换用其他公共网关)。
内容的提问来源于stack exchange,提问作者F0urL34f
相关产品推荐
相关产品推荐

